守护进程创建的基本条件:
1.在后台运行
2.与终端无关
创建过程:
1.父进程调用fork()产生后台子进程:
fork()调用后,父进程退出,子进程运行在后台。这种情况下,子进程属于父进程的进程组,那么子进程不是所属进程组的组长,所以子进程可以调用setid()产生新的会话期。[1]
2.调用setsid()函数产生新的会话期,并且失去控制终端:
setsid()后,产生了新的会话期,这时的子进程是新的进程组与会话期的组长进程,同时,失去了原来与父进程共用的终端。
3.忽略SIGNUP信号:
signal(SIGHUP,SIG_IN)
这是因为后面fork()孙子进程后,子进程退出时要向会话期内的所有进程发送SIGUP信号,如果不忽略,会让进程中止。
4.再次调用fork()产生孙子进程,子进程退出:
产生的孙子进程无法重新打开控制终端,而且不会由于子进程的SIGHUP信号中断,这时,守护进程就已经产生了。
5.其他处理:
改变工作目录
关闭已经打开的文件描述符
重新设置创建文件的掩码 等等
代码示例不在写在这里了,网上很多的。
想到的几个问题(如果发现错误,请指出或者email我):
1.在父进程setsid会如何?
setsid是为了产生新的会话期,调用setsid的进程如果已经是进程组的组长,那么会出错返回。(就是说,进程组ID不等于进程ID的时候才能调用)
2.为什么要在子进程里再fork()出一个孙子进程?子进程中不是已经关闭终端了吗?
这样可以防止控制终端重新打开。
3.什么是进程组?
进程组是一个或多个进程的集合,每个进程组有一个唯一的进程组ID,有一个组长进程。组长进程的进程ID与进程组ID相同。
4.我关于进程组的问题:
系统从init进程开始fork,那么基本上所有进程都是init进程组的。再推下去,同一个进程是可以属于不同的进程组的,他可以在进程组A里为非组长进程,而同时做为进程组B的进程组组长。
阅读(1016) | 评论(0) | 转发(0) |