守护进程的定义
守护进程也称为精灵进程(daemon)是一种生存周期较长的特殊进程。它常常伴随系统自举时启动,在系统关闭时终止。没有控制终端,仅在后台运行,独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。
守护进程的特征
可以使用ps -axj命令查看相应的信息
守护进程不具有控制终端,其终端名(TTY)设置为问号(?)。
守护进程的实现
守护进程的实现具有严格的规则
1、调用umask将文件模式创建屏蔽字设置为0,确保守护进程可以创建一个可读可写的文件。
2、调用fork,然后使父进程退出(exit)。
3、调用setsid创建一个新会话。作用有三,其一使得该进程成为新会话的首进程;其二使得该进程成为新进程组的组长进程;其三确保该进程没有控制终端。
4、将当前工作目录设置为根目录。
5、关闭不再需要的文件描述符。
6、忽略必要的信号防止守护进程意外退出。忽略SIGCHLD信号,如果守护进程创建了子进程后,子进程退出时会自动被操作系统回收,不需要调用waitpid。如果你从shell里启动一个进程,当终端断开时,终端的控制进程也就是shell会给本会话期的所有进程发送SIGHUP信号,这样你不忽略该信号的话,只要你一断开终端你的进程就会退出.所以守护进程可以通过忽略SIGHUP来达到.
具体实例如下
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
int daemon_createDaemon(void)
{
pid_t pid;
signal(SIGTTOU,SIG_IGN);
signal(SIGTTIN,SIG_IGN);
signal(SIGTSTP,SIG_IGN);
signal(SIGHUP ,SIG_IGN);
pid = fork();
if (pid > 0) { // 结束父进程,将子进程置为后台进程
exit(0);
}
else if (pid < 0) {
return -1;
}
// 创建新进程组,让子进程脱离所用终端
setsid();
// 重新创建子进程,退出父进程,保证该进程不是进程组组长
pid = fork();
if (pid > 0) {
exit(0);
}
else if (pid < 0) {
return -1;
}
// 关闭所有从父进程继承的文件描述符
for (int i = 0; i < NOFILE; ++i) {
close(i);
}
// 改变工作目录
chdir("/");
// 重置文件屏蔽字为0
umask(0);
// 忽略SIGCHLD信号
signal(SIGCHLD, SIG_IGN);
return 0;
}
int main()
{
daemon_createDaemon();
return 0;
}
版权声明:本文为liang_zhaocong原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。