原文地址:http://blog.csdn.net/yuxue_23/article/details/12162785
1.进程、进程组与会话关系及其特性。
(1) 每个进程都有一个进程ID唯一识别(pid_t pid=getpid());
(2) 每个进程都属于一个进程组(getpgrp()),进程组属于一个会话(getsid(getpid())),是子集关系,即包含与被包含。
(3) 进程组通常与同一作业相关联,接收同一终端的各种信号。进程组有唯一的进程组ID(类型与进程ID相同),可以有组长进程(进程ID与进程组ID相同),进程组中有任何一个进程存在,则进程组存在,与组长进程是否存在无关。进程组最后一个进程可能终止或者转移到另一个进程组(setpgid())。
(4) 进程只能修改自己或者自己的子进程的进程组ID,但是子进程调用exec函数后就不能在改变子进程的进程组ID。
(5) 一般修改进程组ID函数是在fork函数之后调用,父进程设置子进程的进程组ID,而且子进程设置自己的进程组ID,存在冗余,但是可以保证存在父子进程运行顺序不确定的情况下,在父子进程都认为子进程进程组ID已经设置的情况时,该事件已经发生完成。
(6) waitpid函数可以用来等待指定进程组的进程终止(pid==0或pid<-1),kill函数也可向进程组发送信号(pid==0或pid<-1)。
(7)会话(session)是多个进程组的集合,通常用shell管道线将几个编程一组。调用setsid()建立新的会话。
(8) setsid创建新会话的条件是,当前调用进程不能是进程组组长进程,否则返回错误。正常情况下会完成:(a)该进程变成会话首进程;(b)进程成为新的进程组组长进程;(c)该进程没有控制终端,即使在之前有控制终端,也会断开。
(9) 一般setsid的调用方法为:先fork,然后在子进程调用setsid,因为子进程继承父进程的进程组ID,但是进程ID是最新分配的,两者不可能相等,即子进程不可能是组长进程。
2. 控制终端
(1) 一个会话可以有一个控制终端,通常是登录到其上的终端设备或伪终端设备;
(2) 建立与控制终端相连的会话首进程成为控制进程,即只有会话首进程可能获得控制终端;
(3) 会话的进程组可以分为前台进程组与后台进程组,终端输入与信号都是发给前台任务组(后台进程组不受影响),检测到调制解调器(或网络)断开连接,则将挂断信号发给控制进程(会话首进程)。
3.守护进程是生存期较长的一种进程,一般在系统启动时启动,系统关闭时停止,没有控制终端,后台运行。
守护进程编程规范及详解如下:
(1) 调用umask,将文件模式创建屏蔽字设置为0。因为子进程会继承父进程的文件模式屏蔽字,可能拒绝某些权限设置。保证守护进程的文件运行权限。
(2) 调用fork,然后父进程退出。(a)如果守护进程是由shell启动,父进程终止,会使shell认为该命令已经执行完毕;(b)子进程继承父进程的进程组ID,但有新的进程ID,保证不是组长进程,是调用setsid的前提条件,如1(8)中所述。
(3) 调用setsid,执行1(8)中的三个操作:(a)成为新会话首进程;(b)成为新进程组组长进程;(c)没有控制终端。
(4)再次调用fork,并且父进程终止退出,如此新的子进程就不可能是会话首进程,按照系统V规则,可以防止进程再次取得控制终端,如2(2)中所述。避免取得控制终端的另一个方法为,每次打开一个终端设备都指定O_NOCTTY。
(5) 更改当前工作目录为根目录。因为守护进程一直存在,如果当前工作目录是在一个装配文件系统(挂载系统),该文件系统就不可能被卸载。
(6) 关闭不需要的文件描述符。使用open_max或getrlimit函数获得最高文件描述符值,然后循环关闭。
(7) 一些守护进程打开/dev/null,使其具有文件描述符0、1和2。任何试图读标准输入、写标准输出或标准出错的例程都不会有任何效果。因为守护进程不与任何终端设备相关联。即使守护进程是通过交互会话启动,但是守护进程是后台进程,登录会话的终止并不影响守护进程。
(8) 守护进程的相关输出与报告通过日志系统输出openlog(cmd, LOG_CONS, LOG_DAEMON)。
3.单例守护进程
为了正常运作,某些守护进程实现必须为单例,任何时刻只能运行该守护进程的一个副本。例如要排它的访问一个设备。文件锁与记录锁是一种方法。守护进程创建一个文件,并且加上写锁,此后任何试图创建同样写锁的进程将失败。
4. 守护进程惯例
(1) 守护进程如果使用锁文件,通常放在/var/run目录中,命名方式为name.pid
(2) 如支持配置选项,配置文件通常放在目录/etc中,命名方式为name.conf
(3)守护进程一般只有在启动时候读取配置文件,此后一般不会查看。若修改了配置文件,一种方法是重启守护进程,以使配置文件生效。为了避免麻烦,某些进程捕捉SIGHUP信号,收到信号时重新读取配置文件。因为守护进程不与终端结合,或是无终端的会话首进程,或是孤儿进程组的成员,守护进程并不期望接收SIGHUP。因此可以安全的重复使用。