守护进程及守护进程中两次fork问题

守护进程(daemon)也称为精灵进程,是运行在后台的一种特殊程序。独立于终端控制且周期性地执行某种任务或等待处理某些发生的时间。
守护进程一般7*24小时运行,因为守护进程自成会话,故不受用户注销登录影响,在命名上通常以d结尾。

如何创建:
1.调用umask将文件模式创建屏蔽字设置为0
2.fork,子进程退出
3.setsid创建一个新会话
4. 将当前⼯作⽬录更改为根目录。
5. 关闭不在需要的文件描述符。
6. 其他:忽略SIGCHLD信号。

创建守护进程最关键的一步是调用setsid函数创建一个新的session,并成为session Leader,用setsid函数创建时,不允许当前进程是话首,否则函数返回-1,要保证这一点,可在调用函数前先fork,fork创建的子进程与父进程在同一个进程组,故子进程肯定不是组长进程。

示例:
守护进程及守护进程中两次fork问题

在这里,自己编写了一个守护进程mydaemon,调用系统接口相对简单,将mydaemon 函数调用部分改为setsid(),setsid函数参数缺省时为关闭根目录,关闭文件描述符。

可以看到上面的代码中调用了fork,也有人在setsid函数调用之后再调用一次fork,是对程序的优化,但第二次fork并不是必须。

首先第一次fork:让shell认为这条命令已经终止,不用挂在终端输入上。也是为了后面的setsid函数的进程不再是进程组的组长,如果不是fork子进程,此时的父进程是进程组组长,无法调用setsid。

第二次fork:避免后期进程误操作而再次打开终端。打开一个终端的前提条件是该进程为进程组组长,而通过二次fork,确保第二次fork出来的子进程不会是会话组组长。