使用 nohup
命令创建守护进程,使得程序挂在后台,但是程序执行完成后就会退出,程序的输出会存入 log 文件。
从 fork 开始按按步骤创建
在父进程中执行 fork
函数,并且父进程退出,子进程将被 init 进程托管;
在子进程中使用 setsid
函数创建新的会话,目的是让子进程脱离终端的控制,并且摆脱父进程的影响;
进程是属于进程组的,进程组的组号 gid 就是进程组组长的 pid,登录会话可以包括多个进程组,这些进程组共享一个控制终端,如果想要创建守护进程就要让这个进程脱离出来,自己单独成一个进程组,setsid 就能够将进程完全独立出来,脱离其他进程的控制。
在子进程中调用 chdir
函数让当前的根目录成为子进程的工作目录
使用 umask
函数,把文件创建掩码设为 0,umask(0)
文件创建掩码是指屏蔽掉文件创建时的对应位。由于使用fork函数新建的子进程继承了父进程的文件创建掩码,这就给该子进程使用文件带来了诸多的麻烦。因此,把文件创建掩码设置为0,可以大大增强该守护进程的灵活性。
关闭文件描述符
因为用fork新建的子进程会从父进程那里继承一些已经打开了的文件。这些被打开的文件可能永远不会被守护进程读或写,但它们一样消耗系统资源,可能导致所在的文件系统无法卸载。
用 daemon()
函数直接创建守护进程
#include <unistd.h> int daemon(int nochdir, int noclose);
nochdir
若为 0,将当前工作目录更改为根目录,否则为当前工作目录noclose
若为 0,将标准输入、标准输出、标准错误都重定向到 /dev/null
; 否则不会修改
deamon()
调用了fork()
,如果fork成功,那么父进程就调用_exit()
退出,因此只能通过子进程看到进一步的错误。如果成功函数返回 0,否则返回 -1 并设置 errno。