@time 2019-07-14
@author Ruo_Xiao
一、概念
守护进程是长期运行的、不与终端关联的、后台运行的进程。
二、栗子
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/stat.h>
// 创建守护进程。
int MyDaemon()
{
// 创建子进程。
switch (fork())
{
// 创建线程错误。
case -1:
return -1;
// 创建子进程成功,直接往下运行。
case 0:
break;
// 父进程直接退出。
default:
exit(0);
}
// 运行至此,子进程变成孤儿进程,由 init(systemd) 收养。
// 子进程创建新会话,并成为进程组组长和会话领头进程,与终端脱离关联。
if (setsid() == -1)
return -1;
// 设置为 0,不让其限制文件权限,以免引起混乱。
umask(0);
// 以读写的方式打开黑洞设备。
int fd = open("/dev/null", O_RDWR);
if (fd == -1)
return -1;
if (dup2(fd, STDIN_FILENO) == -1)
return -1;
if (dup2(fd, STDOUT_FILENO) == -1)
return -1;
if (dup2(fd, STDERR_FILENO) == -1)
return -1;
close(fd);
return 0;
}
int main()
{
if (MyDaemon() != 0)
return 1;
while (true)
sleep(1);
return 0;
}
三、其他
1、cmd 指令
ps -axj
显示的守护进程的名字中,带“[]”的是内核守护进程,不带的则是用户级守护进程。
2、守护进程不会收到来自内核的 SIGHUP、SIGINIT 和 SIGWINCH 信号,如果守护进程收到该信号,说明该信号是来自其他进程的。程序员可以将这三个信号用于他用。
在 nginx 中, 配置文件被修改之后,nginx reload 时,就是用 SIGHUP 信号来通知 nginx 来实现上述操作的。
3、拓展
- SIGHUP:终端关闭信号。
- SIGINIT:Ctrl + C 。
- SIGWINCH:终端大小改变信号。
(SAW:Game Over!)