【问题标题】:how to make a process daemon如何制作一个进程守护进程
【发布时间】:2011-07-20 01:01:05
【问题描述】:

我正在尝试了解如何使我的程序成为守护程序。所以我遇到的一些事情一般来说,程序执行以下步骤成为守护程序:

  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;  
}

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

【问题讨论】:

标签: c linux daemon systems-programming


【解决方案1】:

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

【讨论】:

  • 我很高兴现在这是一个答案,而不是隐藏在 cmets 中。也许你可以把它充实一点——链接到标准(或者更好的是,链接到教程或示例)。
  • @deadbeef 这个答案比之前出现的普通link only answers 要好得多。但是,尽管它也非常接近于 link only (无论如何我会认为给定的链接更加稳定)。我会尝试增强答案,给出一个简短的代码示例(特别是因为链接的手册页中没有),或者引用概要。
  • 请注意,daemon 函数符合 POSIX。
  • freedesktop.org/software/systemd/man/daemon.html#SysV%20Daemons 上写着“不应使用 BSD daemon() 函数,因为它仅实现了这些 [15] 步骤的子集。”
【解决方案2】:

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

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

    return 0;
}

【讨论】:

    猜你喜欢
    • 2023-03-02
    • 2014-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多