进程间关系与守护进程

一、进程组

1.1、什么是进程组

提到进程的概念, 其实每一个进程除了有一个进程 ID(PID)之外 还属于一 个进程组。进程组是一个或者多个进程的集合, 一个进程组可以包含多个进程。 每一 个进程组也有一个唯一的进程组 ID(PGID), 并且这个 PGID 类似于进程 ID, 同样是 一个正整数, 可以存放在 pid_t 数据类型中。

ps -eo pid,pgid,ppid,comm | grep test结果如下
PID     PGID     PPID     COMMAND
2830    2830    2259       test-e 选项表示 every 的意思, 表示输出每一个进程信息
-o 选项以逗号操作符(,)作为定界符, 可以指定要输出的列

1.2、组长进程

每一个进程组都有一个组长进程。 组长进程的 ID 等于其进程 ID。我们可以通过 ps 命 令看到组长进程的现象:

ps -o pid,pgid,ppid,comm | cat# 输出结果
PID     PGID     PPID     COMMAND
2806    2806     2805     bash
2880    2880     2806     ps
2881    2880     2806     cat

从结果上看 ps 进程的 PID 和 PGID 相同, 那也就是说明 ps 进程是该进程组的组长进 程, 该进程组包括 ps 和 cat 两个进程。

  • 进程组组长的作用: 进程组组长可以创建一个进程组或者创建该组中的进程
  • 进程组的生命周期: 从进程组创建开始到其中最后一个进程离开为止。注意:主要某个进程组中有一个进程存在, 则该进程组就存在, 这与其组长进程是否已经终 止无关。

二、会话

2.1、什么是会话

刚刚谈到了进程组的概念, 那么会话又是什么呢? 会话其实和进程组息息相关, 会话可以看成是一个或多个进程组的集合, 一个会话可以包含多个进程组。每一个会 话也有一个会话 ID(SID)

 通常都是使用管道将几个进程编成一个进程组。 如上图的进程组 2 和进程组 3 可能是由下列命令形成的:

Shell
[node@localhost code]$ proc2 | proc3 &
[node@localhost code]$ proc4 | proc5 | proc6 &
# &表示将进程组放在后台执行

举一个例子观察一下这个现象:

Shell
# 用管道和 sleep 组成一个进程组放在后台运行
[node@localhost code]$ sleep 100 | sleep 200 | sleep 300 &
# 查看 ps 命令打出来的列描述信息
[node@localhost code]$ ps axj | head -n1
# 过滤 sleep 相关的进程信息
[node@localhost code]$ ps axj | grep sleep | grep -v grep
# a 选项表示不仅列当前⽤户的进程,也列出所有其他⽤户的进程
# x 选项表示不仅列有控制终端的进程,也列出所有⽆控制终端的进程
# j 选项表示列出与作业控制相关的信息, 作业控制后续会讲
# grep 的-v 选项表示反向过滤, 即不过滤带有 grep 字段相关的进程
# 结果如下PPID     PID     PGID     SID     TTY     TPGID     STAT     UID     TIME
COMMAND
2806    4223     4223    2780   pts/2      4229        S    1000     0:00 sleep
100
2806    4224     4223    2780   pts/2      4229        S    1000     0:00 sleep
200
2806    4225     4223    2780   pts/2      4229        S    1000     0:00 sleep
300

从上述结果来看 3 个进程对应的 PGID 相同, 即属于同一个进程组。

2.2、如何创建会话

可以调用 setseid 函数来创建一个会话, 前提是调用进程不能是一个进程组的组长。

C
#include <unistd.h>
/**功能:创建会话*返回值:创建成功返回 SID, 失败返回-1
*/
pid_t setsid(void);

该接口调用之后会发生:

  • 调用进程会变成新会话的会话首进程。 此时, 新会话中只有唯一的一个进程
  • 调用进程会变成进程组组长。 新进程组 ID 就是当前调用进程 ID
  • 该进程没有控制终端。 如果在调用 setsid 之前该进程存在控制终端, 则调 用之后会切断联系

需要注意的是: 这个接口如果调用进程原来是进程组组长, 则会报错, 为了避免这种情况, 我们通常的使用方法是先调用 fork 创建子进程, 父进程终止, 子进程继续执行, 因为子进程会继承父进程的进程组 ID, 而进程 ID 则是新分配的, 就不会出现错误的情况。

2.3、会话 ID(SID)

上边我们提到了会话 ID, 那么会话 ID 是什么呢? 我们可以先说一下会话首进程, 会 话首进程是具有唯一进程 ID 的单个进程, 那么我们可以将会话首进程的进程 ID 当做 是会话 ID。注意:会话 ID 在有些地方也被称为 会话首进程的进程组 ID, 因为会话首 进程总是一个进程组的组长进程, 所以两者是等价的。

三、控制终端

先说一下什么是控制终端:

在 UNIX 系统中,用户通过终端登录系统后得到一个 Shell 进程,这个终端成为 Shell 进程的控制终端。控制终端是保存在 PCB 中的信息,我们知道 fork 进程会复制 PCB 中的信息,因此由 Shell 进程启动的其它进程的控制终端也是这个终端。默认情况下没有重定向,每个进程的标准输入、标准输出和标准错误都指向控制终端,进程从标准输入读也就是读用户的键盘输入,进程往标准输出或标准错误输出写也就是输出到显示器上。另外会话、进程组以及控制终端还有一些其他的关系,我们在下边详细介绍一下:

  • 一个会话可以有一个控制终端,通常会话首进程打开一个终端(终端设备或 伪终端设备)后,该终端就成为该会话的控制终端。
  • 建立与控制终端连接的会话首进程被称为控制进程
  • 一个会话中的几个进程组可被分成一个前台进程组以及一个或者多个后台进程组。
  • 如果一个会话有一个控制终端,则它有一个前台进程组,会话中的其他进程 组则为后台进程组。
  • 无论何时进入终端的中断键(ctrl+c)或退出键(ctrl+\),就会将中断信号 发送给前台进程组的所有进程。
  • 如果终端接口检测到调制解调器(或网络)已经断开,则将挂断信号发送给 控制进程(会话首进程)。

这些特性的关系如下图所示:

 

四、作业控制 

4.1、什么是作业(job)和作业控制(Job Control)

作业是针对用户来讲,用户完成某项任务而启动的进程,一个作业既可以只包含 一个进程,也可以包含多个进程,进程之间互相协作完成任务, 通常是一个进程管道。

Shell 分前后台来控制的不是进程而是作业 或者进程组。一个前台作业可以由多 个进程组成,一个后台作业也可以由多个进程组成,Shell 可以同时运⾏一个前台 作业和任意多个后台作业,这称为作业控制

例如下列命令就是一个作业,它包括两个命令,在执⾏时 Shell 将在前台启动由两 个进程组成的作业:

Shell
[node@localhost code]$ cat /etc/filesystems | head -n 5

运⾏结果如下所示:

Shell
xfs
ext4
ext3
ext2
nodev proc

4.2、作业号

放在后台执⾏的程序或命令称为后台命令,可以在命令的后面加上&符号从而让 Shell 识别这是一个后台命令,后台命令不用等待该命令执⾏完成,就可立即接收 新的命令,另外后台进程执行完后会返回一个作业号以及一个进程号(PID)

例如下面的命令在后台启动了一个作业, 该作业由两个进程组成, 两个进程都在后台运⾏:

[node@localhost code]$ cat /etc/filesystems | grep ext &

执⾏结果如下:

Shell
[1] 2202
ext4
ext3
ext2
# 按下回车
[1]+ 完成 cat /etc/filesystems | grep --color=auto ext
  • 第一⾏表示作业号和进程 ID, 可以看到作业号是 1, 进程 ID 是 2202
  • 第 3-4 ⾏表示该程序运⾏的结果, 过滤/etc/filesystems 有关 ext 的内容
  • 第 6 号分别表示作业号、默认作业、作业状态以及所执⾏的命令

关于默认作业:对于一个用户来说,只能有一个默认作业(+),同时也只能有一 个即将成为默认作业的作业(-),当默认作业退出后,该作业会成为默认作业。

  • +:表示该作业号是默认作业
  • - :表示该作业即将成为默认作业
  • 无符号: 表示其他作业

4.3、作业状态

常见的作业状态如下表所示:

作业状态含义
正在运行【Running】后台作业(&),表示正在运行
完成【Done】作业已完成,返回的状态码为0
完成并退出【Done(code)】作业已完成并退出,返回的状态码为非0
已停止【Stopped】前台作业,当前 Ctrl+Z 挂起
已终止【Terminated】作业被终止

4.4、作业的挂起与切回

4.4.1、作业挂起

执⾏某个作业时,可以通过 Ctrl+Z 键将该作业挂起,然后 Shell 会显示相 关的作业号、状态以及所执⾏的命令信息。

例如运⾏一个死循环的程序, 通过 Ctrl+Z 将该作业挂起, 观察一下对应的作业状态:

C
#include <stdio.h>
int main()
{while (1){printf("hello\n");}return 0;
}

运⾏这个程序, 通过 Ctrl+Z 将该作业挂起:

Shell
# 运行可执行程序
[node@localhost code]$ ./test
#键入 Ctrl + Z 观察现象

运⾏结果如下:

Shell
# 结果依次对应作业号 默认作业 作业状态 运行程序信息
[1]+ 已停止     ./test7

可以发现通过 Ctrl+Z 将作业挂起, 该作业状态已经变为了停止状态

4.4.2、作业切回

如果想将挂起的作业切回,可以通过 fg 命令,fg 后面可以跟作业号或作业的命令名称。如果参数缺省则会默认将作业号为 1 的作业切到前台来执⾏,若当前系 统只有一个作业在后台进⾏,则可以直接使用 fg 命令不带参数直接切回。 具体的参数参考如下:

参数含义
%nn为整数,表示作业号
%string以字符串开头的命令所对应的作业
%?string包含字符串的命令所对应的作业
%+ 或 %%最近提交的一个作业
%-倒数第二个提交的作业

例如把刚刚挂起来的 ./test 作业切回到前台:

Shell
[node@localhost code]$ fg %%

运⾏结果为开始无限循环打印 hello, 可以发现该作业已经切换到前台了。

注意: 当通过 fg 命令切回作业时,若没有指定作业参数,此时会将默认作业切 到前台执行,即带有“+”的作业号的作业

4.5、查看后台执行或挂起的作业

可以直接通过输入 jobs 命令查看本用户当前后台执⾏或挂起的作业

  • 参数-l 则显示作业的详细信息
  • 参数-p 则只显示作业的 PID

例如, 先在后台及前台运⾏两个作业, 并将前台作业挂起, 来用 jobs 命令 查看作业相关的信息:

Shell
# 在后台运行一个作业 sleep
[node@localhost code]$ sleep 300 &
# 运行刚才的死循环可执行程序
[node@localhost code]$ ./test
# 键入 Ctrl + Z 挂起作业
# 使用 jobs 命令查看后台及挂起的作业
[node@localhost code]$ jobs -l

运⾏结果如下所示:

Shell
# 结果依次对应作业号 默认作业 作业状态 运行程序信息
[1]- 2265 运行中         sleep 300 &
[2]+ 2267 停止           ./test7

4.6、作业控制相关的信号

上面我们提到了键入 Ctrl + Z 可以将前台作业挂起,实际上是将 STGTSTP 信号 发送至前台进程组作业中的所有进程, 后台进程组中的作业不受影响。 在 unix 系统中, 存在 3 个特殊字符可以使得终端驱动程序产生信号, 并将信号发送至前 台进程组作业, 它们分别是:

  • Ctrl + C: 中断字符, 会产生 SIGINT 信号
  • Ctrl + \: 退出字符, 会产生 SIGQUIT 信号
  • ▪ Ctrl + Z:挂起字符, 会产生 STGTSTP 信号

终端的 I/O(即标准输入和标准输出)和终端产生的信号总是从前台进程组作业连接 打破实际终端。

五、守护进程

Daemon.hpp

C++
#pragma once#include <iostream>
#include <cstdlib>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>const char *root = "/";
const char *dev_null = "/dev/null";void Daemon(bool ischdir, bool isclose)
{// 1. 忽略可能引起程序异常退出的信号signal(SIGCHLD, SIG_IGN);signal(SIGPIPE, SIG_IGN);// 2. 让自己不要成为组长if (fork() > 0)exit(0);// 3. 设置让自己成为一个新的会话, 后面的代码其实是子进程在走setsid();// 4. 每一个进程都有自己的 CWD,是否将当前进程的 CWD 更改成为 / 根目录if (ischdir)chdir(root);// 5. 已经变成守护进程啦,不需要和用户的输入输出,错误进行关联了if (isclose){close(0);close(1);close(2);}else{// 这里一般建议就用这种int fd = open(dev_null, O_RDWR);if (fd > 0){dup2(fd, 0);dup2(fd, 1);dup2(fd, 2);close(fd);}}
}

六、如何将服务守护进程化

C++
// ./server port
int main(int argc, char *argv[])
{if (argc != 2){std::cout << "Usage : " << argv[0] << " port" <<std::endl;return 0;}uint16_t localport = std::stoi(argv[1]);Daemon(false, false);std::unique_ptr<TcpServer> svr(new TcpServer(localport, HandlerRequest));svr->Loop();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/451788.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SCI英文文献阅读工具【全文翻译】【逐句翻译】

关注B站可以观看更多实战教学视频&#xff1a;hallo128的个人空间 SCI英文文献阅读工具【全文翻译】【逐句翻译】 1. 全文翻译【DeepL】 适用于泛读网址&#xff1a;https://www.deepl.com/zh/translator/files 1.1 前提 文档大小&#xff1a;pdf文档不超过5M&#xff08;可先…

设计模式05-创建型模式(建造者/原型/单例模式/Java)

3.4 建造者模式 3.4.1 建造者模式的定义 动机&#xff1a;方便创建复杂对象&#xff08;一个对象中包含多个成员变量&#xff09; 定义&#xff1a;将一个复杂对象的构建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。建造者模式是一步一步创建一个复杂…

计算机视觉中的最小二乘法:寻找完美交点和直线拟合

Hello&#xff0c;小伙伴们&#xff01;今天我们要聊的是计算机视觉中的一个小技巧——使用最小二乘法来进行交点计算和直线拟合。你有没有想过&#xff0c;如何从一堆杂乱无章的数据点中找到那条最佳拟合直线&#xff1f;或者&#xff0c;如何确定几条直线相交的确切位置&…

OpenCV物体跟踪:使用CSRT算法实现实时跟踪

目录 简介 CSRT算法简介 实现步骤 1. 初始化摄像头和跟踪器 2. 读取视频帧和初始化跟踪 3. 实时跟踪和显示结果 4. 显示和退出 5、结果展示 总结 简介 在计算机视觉和视频处理领域&#xff0c;物体跟踪是一项核心技术&#xff0c;它在监控、人机交互、运动分析等方面…

CSS布局/简单应用

思考下面四个图片如何布局 test1 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</titl…

双十一有啥好用的物品可以推荐购买?2024不可错过的必囤好物清单!

双十一购物狂欢节即将拉开帷幕&#xff0c;许多朋友们可能还在犹豫不决&#xff0c;不知道应该选购哪些商品。别担心&#xff0c;今天我特意为大家精心准备了一份包含五款必囤好物的清单&#xff0c;希望能够帮助大家在双十一期间抢购到心仪的商品&#xff0c;享受购物的乐趣&a…

《米小圈动画成语》|在趣味中学习,在快乐中掌握成语知识!

作为一名家长&#xff0c;我一直希望孩子能够在学习的过程中既感受到乐趣&#xff0c;又能获得真正的知识。成语作为中华文化的精华&#xff0c;虽然意义深远、简洁凝练&#xff0c;但对于一个小学生来说&#xff0c;学习和理解这些言简意赅的成语无疑是一个挑战。尤其是有些成…

将本地文件上传到GIT上

上传文件时&#xff0c;先新建一个空文件&#xff0c;进行本地库初始化&#xff0c;再进行远程库克隆&#xff0c;将要上传的文件放到克隆下来的文件夹里边&#xff0c;再进行后续操作 1.在本地创建文件夹&#xff0c;将要上传的文件放在该文件下 2.在该文件页面中打开Git Bas…

ai字幕用什么软件制作?6款视频加字幕工具分享!

在视频制作和后期处理中&#xff0c;字幕的添加是一个重要的环节。随着AI技术的发展&#xff0c;越来越多的软件开始支持AI自动加字幕功能&#xff0c;使得字幕的制作变得更加简单和高效。本文将为大家介绍几款常用的AI字幕制作软件&#xff0c;并详细讲解如何使用AI自动加字幕…

TDD(测试驱动开发)是否已死?

Rails 大神、创始人 David Heinemeier Hansson 曾发文抨击TDD。 TDD is dead. Long live testing. (DHH) 此后, Kent Beck、Martin Fowler、David Hansson 三人就这个观点还举行了系列对话&#xff08;辩论&#xff09; Is TDD Dead? 笔者作为一个多年在软件测试领域摸索的人&…

Linux——动态卷的管理

确保已经设置了对应的动态卷的驱动&#xff08;provisioner 制备器&#xff09;基于动态驱动创建对应的存储类创建PVC &#xff08;PVC 将会自动根据大小、访问模式等创建PV&#xff09;Pod的spec 中通过volumes 和 volumemounts 来完成pvc 的绑定和pvc对应pv的挂载删除pod 不…

Java基于微信小程序的公考学习平台的设计与实现,附源码+文档

博主介绍&#xff1a;✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&…

新魔百和cm311-5 ZG 4+16g 卡刷语音固件教程

新魔百和cm311-5_国科6323_蓝牙版刷 准备工具&#xff1a;U盘、短接工具、 固件包&#xff1a;CM311-5-zg链接 https://pan.baidu.com/s/1f5NxmCGCO0F84RQRBrSMRg 提取码: b7f1 操作步骤&#xff1a; 1、用不大于8G U盘&#xff0c;先做FAT32&#xff0c;2048块单分区格式化后…

Yoga Pro 13s 2021款Intel处理器ITL版(82HJ)原厂Win10系统镜像下载

lenovo联想Yoga-PRO-13S笔记本电脑恢复开箱状态预装OEM系统Windows10安装包 链接&#xff1a;https://pan.baidu.com/s/1YjGCXe_Zxkwcgum3TWZx5g?pwdshqu 提取码&#xff1a;shqu 联想原装系统自带所有驱动、出厂主题壁纸、系统属性联机支持标志、系统属性专属LOGO标志、O…

桂林旅游一点通:SpringBoot平台应用

3系统分析 3.1可行性分析 通过对本桂林旅游景点导游平台实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本桂林旅游景点导游平台采用SSM框架&#xff0c;JAVA作…

C++虚函数的默认参数是静态绑定还是动态绑定

C虚函数的默认参数是静态绑定还是动态绑定 或者问&#xff1a;是在编译阶段确定的还是在运行阶段确定的 答案是&#xff1a;编译阶段&#xff0c;也就是静态绑定的 #include <iostream>class Base { public:virtual void func(int x 10) {std::cout << "Ba…

pikachu靶场CSRF-get测试报告

目录 一、测试环境 1、系统环境 2、使用工具/软件 二、测试目的 三、操作过程 1、抓包使用burp生成csrf脚本 四、源代码分析 五、结论 一、测试环境 1、系统环境 渗透机&#xff1a;本机(127.0.0.1) 靶 机&#xff1a;本机(127.0.0.1) 2、使用工具/软件 Burp sui…

字节跳动实习生投毒自家大模型细节曝光 影响到底有多大?

10月19日&#xff0c;字节跳动大模型训练遭实习生攻击一事引发广泛关注。据多位知情人士透露&#xff0c;字节跳动某技术团队在今年6月遭遇了一起内部技术袭击事件&#xff0c;一名实习生因对团队资源分配不满&#xff0c;使用攻击代码破坏了团队的模型训练任务。 据悉&#xf…

信息学竞赛:是靠努力,还是靠天赋?

信息学竞赛&#xff08;OI&#xff09;近年来在学生和家长中越来越受欢迎。这项竞赛不仅可以培养孩子的编程能力和逻辑思维能力&#xff0c;还为一些有志于名校的学生提供了一条升学的捷径。然而&#xff0c;许多人会问&#xff1a;参加信息学竞赛成功的关键在于天赋还是努力&a…

TwinCAT3 软件介绍

文章目录 软件界面各个窗口说明如下图&#xff1a; 工具栏说明如下&#xff1a; 调试按钮说明如下&#xff1a; TwinCAT运行环境按钮说明如下&#xff1a; PLC项目环境说明如下&#xff1a; TwinCAT系统状态图标说明如下&#xff1a; PLC程序状态说明如下&#xff…