Daemon进程创建过程


Daemon创建过程:
1、fork,创建子进程。退出父进程。
2、setsid,创建新会话。脱离原会话、进程组、控制终端。
再次fork,与终端完全脱离。第二次fork的意义???? 先脱离原父进程,改成init进程为父进程;但此时是新建了一个进程组,当前进程是leader,即关联到session、tty,需要脱离;所以再次fork,脱离tty,则不再受到会话的干扰,变成完全独立的后台进程。
3、chdir,修改工作目录。通常改到根目录,也可以是tmp等其他目录。
4、umask,重设默认文件权限。文件权限掩码设置为0,可恢复所有默认权限。
5、close,关闭不需要的文件描述符(stdin,stdout,stderr等)。
6、signal,处理守护进程退出。设置处理kill操作导致的SIGTERM信号的handler。

### Linux守护进程创建过程详解 在Linux系统中,守护进程Daemon)是一种特殊的后台进程[^1]。它通常没有控制终端,无法直接与用户交互,并且能够在用户登录或注销时持续运行[^4]。守护进程广泛应用于服务器环境中的长时间任务处理,例如日志记录、网络服务等[^3]。 创建守护进程过程可以分为以下几个关键步骤: #### 1. 创建进程并退出父进程 通过`fork()`系统调用创建一个子进程,并让父进程退出。这样可以确保子进程不会被终端信号影响。父进程退出后,子进程会被`init`进程(PID为1)接管[^2]。 ```c pid_t pid = fork(); if (pid < 0) { // 错误处理 exit(EXIT_FAILURE); } if (pid > 0) { // 父进程退出 exit(EXIT_SUCCESS); } ``` #### 2. 创建新会话 调用`setsid()`函数创建一个新的会话,使进程脱离原来的会话和进程组[^5]。这一步非常重要,因为只有脱离了原来的会话,进程才能真正成为守护进程。 ```c if (setsid() < 0) { // 错误处理 exit(EXIT_FAILURE); } ``` #### 3. 改变当前工作目录 将当前工作目录更改为根目录(`/`),以避免守护进程占用其他文件系统的挂载点。如果守护进程需要访问特定目录,则可以将其更改为该目录。 ```c chdir("/"); ``` #### 4. 重设文件权限掩码 通过调用`umask(0)`重设文件权限掩码,以确保守护进程创建的文件具有预期的权限。 ```c umask(0); ``` #### 5. 关闭不必要的文件描述符 关闭所有打开的文件描述符(如标准输入、标准输出、标准错误),以释放资源并防止对终端的意外访问。 ```c close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); ``` #### 6. 重新定向标准输入、输出和错误 将标准输入、输出和错误重定向到`/dev/null`或其他适当的文件,以防止守护进程尝试写入终端[^5]。 ```c open("/dev/null", O_RDONLY); open("/dev/null", O_WRONLY); open("/dev/null", O_RDWR); ``` #### 7. 编写日志或状态信息 守护进程通常会将日志信息写入文件或使用`syslog`系统进行记录。可以通过配置文件指定日志路径和级别[^3]。 ```c openlog("mydaemon", LOG_PID, LOG_DAEMON); syslog(LOG_INFO, "Daemon started."); closelog(); ``` #### 8. 处理信号 守护进程应设置信号处理器来捕获和处理特定信号(如`SIGHUP`、`SIGTERM`等)。这有助于实现平滑重启或优雅退出[^4]。 ```c struct sigaction sa; sa.sa_handler = handler_function; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sigaction(SIGHUP, &sa, NULL); ``` ### 完整代码示例 以下是一个简单的守护进程创建示例: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <signal.h> #include <syslog.h> void daemonize() { pid_t pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } if (pid > 0) { exit(EXIT_SUCCESS); } if (setsid() < 0) { exit(EXIT_FAILURE); } chdir("/"); umask(0); close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); open("/dev/null", O_RDONLY); open("/dev/null", O_WRONLY); open("/dev/null", O_RDWR); } int main() { daemonize(); openlog("mydaemon", LOG_PID, LOG_DAEMON); syslog(LOG_INFO, "Daemon started."); closelog(); while (1) { sleep(60); // 模拟守护进程的主循环 } return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值