子进程异步清除
SIGCHLD信号:子进程终止时,向父进程自动发送,编写此信号处理例程,异步清除子进程
#include <signal.h> #include <string.h> #include <sys/types.h> #include <sys/wait.h> sig_atomic_t child_exit_status; extern "C" { void CleanUp(int sig_num) { int status; wait(&status); //清除子进程 child_exit_status = status; //存储子进程的状态 } } int main() { //处理SIGCHLD信号 struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = &CleanUp; sigaction(SIGCHLD,&sa, NULL); //正常处理代码在此,例如调用fork()创建子进程 return 0; }
创建守护进程的步骤
- 创建新进程:新进程将成为未来的守护进程
- 守护进程的父进程退出:保证祖父进程确认父进程已结束,且守护进程不是组长进程
- 守护进程创建新进程组和新会话:并成为两者的首进程,此时刚创建的新会话还没有关联控制终端
- 改变工作目录:守护进程一般随系统启动,工作目录不应该继续使用继承的工作目录
- 重设文件权限掩码:不需要继承文件权限掩码
- 关闭所有文件描述符:不需要继承任何打开的文件描述符
- 标注流重定向到/dev/null
#include <sys/types.h> #include <sys/stat.h> #include <stdlib.h> #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <linux/fs.h> int main() { pid_t pid = fork(); if (pid == -1) { return -1; } else if (pid != 0) exit(EXIT_SUCCESS); //子进程 if (setsid() == -1) return -2; //设置工作目录 if (chdir("/") == -1) return -3; //重设文件权限掩码 umask(0); //关闭文件描述符 for (int i = 0; i < 3; i++) close(i); //重定向标准流 open("/dev/null", O_RDWR); dup(0); dup(0); //守护进程的实际工作代码在此 return 0; }
守护进程创建函数daemon()
实现上述功能,减轻编写守护进程的负担