如何制作进程守护进程

Reg*_*ser 67 c linux daemon systems-programming

我试图理解如何使我的程序成为守护进程.所以我遇到的一些事情通常,程序执行以下步骤来成为守护进程:

  1. 打电话fork( ).
  2. 在父母中,打电话exit( ).这可以确保原始父级(守护程序的祖父级)满足其子级终止,守护程序的父级不再运行,并且守护程序不是进程组领导者.最后一点是成功完成下一步的要求.

  3. 调用setsid( ),为守护进程提供一个新的进程组和会话,两者都将其作为领导者.这也确保了进程没有关联的控制终端(因为进程刚刚创建了一个新会话,并且不会分配一个).

  4. 通过将工作目录更改为根目录chdir( ).这样做是因为继承的工作目录可以在文件系统上的任何位置.守护进程倾向于在系统正常运行时间内运行,并且您不希望保持一些随机目录打开,从而阻止管理员卸载包含该目录的文件系统.

  5. 关闭所有文件描述符.

  6. 打开文件描述符0,1和2(标准输入,标准输出和标准错误)并将其重定向到/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 (void)
{
    pid_t pid;
    int i;

    /* create new process */
    pid = fork ( );  
    if (pid == -1)  
        return -1;  
    else if (pid != 0)  
        exit (EXIT_SUCCESS);  

    /* create new session and process group */  
    if (setsid ( ) == -1)  
        return -1;  

    /* set the working directory to the root directory */  
    if (chdir ("/") == -1)  
        return -1;  

    /* close all open files--NR_OPEN is overkill, but works */  
    for (i = 0; i < NR_OPEN; i++)  
        close (i);  

    /* redirect fd's 0,1,2 to /dev/null */  
    open ("/dev/null", O_RDWR);  
    /* stdin */  
    dup (0);  
    /* stdout */  
    dup (0);  
    /* stderror */  

    /* do its daemon thing... */  

    return 0;  
}
Run Code Online (Sandbox Code Playgroud)

有人可以给我一些指向某些程序的现有源代码的链接,比如Apache,这样我就可以更深入地理解这个过程.

dea*_*eef 17

如果您正在寻找一种干净的方法,请考虑使用标准的api int daemon(int nochdir, int noclose);.手册页非常简单,自我解释.手册页.经过良好测试的api远远超过了我们自己实现的便携性和稳定性.

  • @deadbeef这个答案比普通的答案要好得多[http://link onlyflow_questions/323508/what-to-do-with-broken-but-highly-upvoted-link-only-以前出现的答案).但是,它也非常接近_link only_(无论如何我会认为给定的链接更加稳定).我会尝试增强答案,给出一个简短的代码示例(特别是因为链接的手册页中没有),或引用概要. (2认同)
  • 请注意,[守护程序](http://man7.org/linux/man-pages/man3/daemon.3.html)函数不符合**POSIX标准. (2认同)
  • 在https://www.freedesktop.org/software/systemd/man/daemon.html#SysV%20Daemons上写道"不应该使用BSD`守护进程()`函数,因为它只实现了这些函数的一部分[15]步骤." (2认同)