【问题标题】:Creating daemon process in UNIX enviroment在 UNIX 环境中创建守护进程
【发布时间】:2019-05-19 03:39:34
【问题描述】:

我从 APUE 中选择了以下示例:

void daemonize(const char* cmd)
{
        int i,fd0,fd1,fd2;
        pid_t pid;
        struct rlimit r1;
        struct sigaction sa;

        //clear all file masks
        umask(0);

        //get max number of file descriptors
        if(getrlimit(RLIMIT_NOFILE,&r1) < 0)
        {
                perror("error getting file descriptor size");
                return;
        }

        //become a session leader
        if((pid = fork()) < 0)
        {
                perror("error forking");
                return;
        }
        else if(pid == 0)
        {
                setsid();
        }
        else
        {
                exit(0); //parent exits
        }

        sa.sa_handler = SIG_IGN;
        sigemptyset(&sa.sa_mask);
        sa.sa_flags = 0;
        if(sigaction(SIGHUP,&sa,NULL) < 0)
        {
                return;
        }

        if((pid = fork()) < 0)
        {
                return;
        }
        else if(pid != 0)
        {
                exit(0); //parent
        }

        //child continues

        syslog(LOG_ERR,"chile continuing with pid : %d",getpid());
        //change the working directory
        if(chdir("/") < 0)
        {
                return;
        }

        if(r1.rlim_max == RLIM_INFINITY)
                r1.rlim_max = 1024;
        for(i=0;i<r1.rlim_max;i++)
                close(i);

        //attach the file descriptors to /dev/null
        fd0 = open("/dev/null",O_RDWR);
        fd1 = dup(0);
        fd2 = dup(0);

        //initialize the log file
        openlog(cmd, LOG_CONS,LOG_DAEMON);
        if(fd0!=0 || fd1!=1 || fd2!=2)
        {
                syslog(LOG_ERR,"unexpected file descriptors %d %d %d\n",fd0,fd1,fd2);
                exit(1);
        }
}


int main()
{
        daemonize("date");
        pause();    //how is this working???
}

我不明白主函数中的pause() 是如何工作的?我所期待的是,既然我们已经为daemonize() 中的父进程完成了exit(0),它应该已经退出并导致main() 进程正常终止。它应该永远不会返回到main(),甚至不应该发生对pause() 的调用。为什么它没有终止,为什么pause() 被调用?

【问题讨论】:

    标签: c linux fork systems-programming


    【解决方案1】:

    代码分叉了两次,产生了父、子和孙。前两个各exit(0);最后从daemonize返回。

    【讨论】:

    • @aah... 我错过了。谢谢。事实上,我有那么一瞬间忘记了孙子仍将作为 gradparent 执行代码(除了少数基于 pid 的 if-checks)。
    • 请再问一个问题,为什么在我们已经完成setsid() 并开始一个新会话时,我们在这里调用了第二个fork()。在setsid() 之后继续作为会话和组长是否有问题?
    • @insane:这在第 426 页顶部的注释中进行了解释:即使它碰巧打开了终端设备,它也会阻止守护进程获取控制终端。
    猜你喜欢
    • 1970-01-01
    • 2010-10-19
    • 2013-07-31
    • 2021-05-11
    • 1970-01-01
    • 2011-11-09
    • 2017-03-13
    • 2015-02-25
    相关资源
    最近更新 更多