69

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

  1. 打电话fork( )
  2. 在父级中,调用exit( ). 这确保了原始父进程(守护进程的祖父进程)对其子进程终止、守护进程的父进程不再运行以及守护进程不是进程组领导感到满意。最后一点是成功完成下一步的必要条件。

  3. Call 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;  
}

有人可以给我一个链接到一些程序(如 Apache)的现有源代码,以便我可以更深入地理解这个过程。

4

2 回答 2

21

如果您正在寻找一种干净的方法,请考虑使用标准 api- int daemon(int nochdir, int noclose);。手册页非常简单且不言自明。手册页。一个经过良好测试的 api 在可移植性和稳定性方面远远超过我们自己的实现。

于 2016-05-22T09:55:50.217 回答
2

在 Linux 中,可以使用以下方法轻松完成:

int main(int argc, char* argv[])
{
    daemon(0,0);
    while(1)
    {
        sleep(10)
        /*do something*/
    }

    return 0;
}
于 2018-01-28T16:27:59.360 回答