1. 进程组

每个进程除了有一个进程ID之外,还属于一个进程组。进程组是一个或多个进程的集合。通常,它们与同一作业相关联,可以接收来自同一终端的各种信号。每个进程组有一个唯一的进程组ID。每个进程组都可以有一个组长进程。组长进程的标识是,其进程组ID等于其进程ID(也就是已存在的组长进程不能创建新的进程组),。

组长进程可以创建一个进程组,创建该组中的进程,然后终止。只要在某个进程组中一个进程存在,则该进程组就存在,这与其组长进程是否终止无关。
一个进程可以为自己或子进程设置进程组ID

2.作业

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

作业与进程组的区别:如果作业中的某个进程又创建了子进程,则子进程不属于作业。一旦作业运行结束,Shell就把自己提到前台,如果原来的前台进程还存在(如果这个子进程还没终止),它自动变为后台进程组。

3.会话

会话(Session)是一个或多个进程组的集合。

一个会话可以有一个控制终端。这通常是登陆到其上的终端设备(在终端登陆情况下)或伪终端设备(在网络登陆情况下)。建立与控制终端连接的会话首进程被称为控制进程。一个会话中的几个进程组可被分为一个前台进程组以及一个或多个后台进程组。所以一个会话中,应该包括控制进程(会话首进程),一个前台进程组和任意后台进程组。
 
4.守护进程
 守护进程也叫demon进程。守护进程的一个主要的是不受用户和终端,或者其他的变化而受到影响。所以,守护进程要脱离终端控制必须要单独创建会话,因为一个会话只能有一个控制终端,此后守护进程没有打开新的终端,同时又失去当前终端的控制,至此守护进程不受终端影响。
由于一个控制终端需要一个控制进程,当创建新会话之后,创建会话的进程成为控制进程,同时成为新的进程组组长。由于进程组长不能再成为其他进程组的组长,所以我们要确保守护进程在创建新的会话前不能是进程组长。只要在当前进程创建子进程,通过子进程创建会话就没问题了。父进程没再处理任何逻辑可以直接exit。
守护进程编程的步骤:
1、创建子进程,父进程退出
作用:子进程能在创建会话前能确定为不是组长进程,为后续创新会话做铺垫
2、在子进程上创建新的会话,调用setsid()函数
作用:子进程脱离当前的终端控制
3、改变当前目录为根目录
作用:由于子进程已成为守护进程,不再受终端控制,如果不把当前目录挂载在根目录下,后续要是卸载当前目录的文件系统就卸载不了。
4、重设文件权限的掩码
作用:由于子进程继承了父进程的文件权限掩码,同时后面不再受终端控制,为了让守护进程在文件系统的使用上更加灵活,可以重设文件权限掩码。
5、关闭文件描述符号
作用:同样由于子进程继承了父进程的文件权限掩码,同时后面不再受终端控制,继承的打开文件不会用到,浪费文件系统资源,而且会导致无法卸载,最好关掉已打开的所有文件描述符。至于标准输入输出,错误输出可以重定向到/dev/null。

10-07 16:12