摘要:实现后台进程的daemonize函数
引言:
在Linux系统中,后台进程指的是没有任何终端控制的进程,它们通常被称为守护进程或者称为 daemon。
daemon 进程的特点是在系统启动时就开始
实现后台进程的daemonize函数
引言:
在Linux系统中,后台进程指的是没有任何终端控制的进程,它们通常被称为守护进程或者称为 daemon。
daemon 进程的特点是在系统启动时就开始运行,一直到系统关闭,这些进程的生命周期和用户的会话无关。
这篇文章将要介绍 daemonize 函数, 它是 Linux 下实现守护进程的一个典型方法。
daemonize 函数工作原理:
daemonize 函数要做的主要工作是将程序从前台进程变为后台进程, 使程序脱离终端控制, 以便在用户注销或者关闭终端时保持运行状态。
daemon运行的主要步骤如下:
- 在父进程中调用 exit,终止父进程。
- 创建新的会话, 在新的会话中运行子进程。
- 将工作目录更改为根目录, 以避免 directory 挂载导致的Umount失败。
- 关闭不需要的文件描述符, 例如标准输入标准输出标准错误。
- 让子进程成为新会话的领头进程, 拥有新会话的权限。
- 创建一个子进程, 然后退出父进程,继续在子进程中工作。
- 在子进程中设置文件权限掩码为0(umask(0)), 使得进程创建的文件可以任何人读写。
- 关闭不需要的文件描述符以及独占控制终端
- 进入循环程序, 作为后台进程一直等待。
实现代码:
接下来是一个简要的实现代码,该代码可以用来实现daemonize函数, 实现daemon进程:
int
daemonize(const char *cmd)
{
int fd0, fd1, fd2;
pid_t pid;
struct rlimit rl;
struct sigaction sa;
/* Clear file creation mask. */
umask(0);
/* Get maximum number of file descriptors. */
if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
fprintf(stderr, \"%s: can't get file limit\
\", cmd);
return -1;
}
/* Become a session leader to lose controlling TTY. */
if ((pid = fork()) < 0) {
fprintf(stderr, \"%s: can't fork\
\", cmd);
return -1;
} else if (pid != 0) /* parent */
exit(0);
setsid();
/* Ensure future opens won't allocate controlling TTYs.*/
sa.sa_handler = SIG_IGN;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGHUP, &sa, NULL) < 0) {
fprintf(stderr, \"%s: can't ignore SIGHUP\
\", cmd);
return -1;
}
if ((pid = fork()) < 0) {
fprintf(stderr, \"%s: can't fork\
\", cmd);
return -1;
} else if (pid != 0)
exit(0);
/* Change the current working directory to the root so
we won't block mount points.*/
if (chdir(\"/\") < 0) {
fprintf(stderr, \"%s: can't change directory to /\
\", cmd);
return -1;
}
/* Close all open file descriptors. */
if (rl.rlim_max == RLIM_INFINITY)
rl.rlim_max = 2048;
for (int i = 0; i < rl.rlim_max; i++)
close(i);
/* Attach file descriptors 0, 1, and 2 to /dev/null*/
fd0 = open(\"/dev/null\", O_RDWR);
fd1 = dup(0);
fd2 = dup(0);
/* Initial logging. */
openlog(cmd, LOG_CONS, LOG_DAEMON);
if (fd0 != 0 || fd1 != 1 || fd2 != 2) {
syslog(LOG_ERR, \"unexpected file descriptors %d %d %d\", fd0, fd1, fd2);
exit(1);
}
}
:
daemonize 函数充分简化了 Linux 系统下的守护进程编码过程,其实现代码切实可行,值得参考观摩!
作者:Kathy
版权声明:本站部分常识内容收集于其他平台,若您有更好的常识内容想分享可以联系我们哦!



