摘要:实现后台进程的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
版权声明:本站部分常识内容收集于其他平台,若您有更好的常识内容想分享可以联系我们哦!