swoole_process源码分析之daemon过程

版权声明:转载请注明来源 https://blog.csdn.net/u013702678/article/details/82928917

swoole_process提供的daemon用于使当前进程蜕变为一个守护进程。

//低于1.9.1的版本
bool swoole_process::daemon(bool $nochdir = false, bool $noclose = false);
//1.9.1或更高版本
bool swoole_process::daemon(bool $nochdir = true, bool $noclose = true);
  • $nochdir,为true表示不要切换当前目录到根目录。
  • $noclose,为true表示不要关闭标准输入输出文件描述符。

下面我们分析下其流程。

static PHP_METHOD(swoole_process, daemon)
{
    zend_bool nochdir = 1;
    zend_bool noclose = 1;
    
    //解析输入参数信息,这两个参数具体的含义请参考上面php接口描述
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|bb", &nochdir, &noclose) == FAILURE)
    {
        RETURN_FALSE;
    }

    //调用daemon函数,同时返回其处理结果
    RETURN_BOOL(daemon(nochdir, noclose) == 0);
}
int daemon(int nochdir, int noclose)
{
    pid_t pid;

    if (!nochdir && chdir("/") != 0)//未设置不切换根目录,切换到根目录失败
    {
        swWarn("chdir() failed. Error: %s[%d]", strerror(errno), errno);
        return -1;
    }

    if (!noclose)//要关闭描述符
    {
        int fd = open("/dev/null", O_RDWR);//打开/dev/null文件
        if (fd < 0)
        {
            swWarn("open() failed. Error: %s[%d]", strerror(errno), errno);
            return -1;
        }

        if (dup2(fd, 0) < 0 || dup2(fd, 1) < 0 || dup2(fd, 2) < 0)//将标准输入、错误、输出重定向到fd中
        {
            close(fd);
            swWarn("dup2() failed. Error: %s[%d]", strerror(errno), errno);
            return -1;
        }

        close(fd);//关闭文件描述符
    }

    pid = fork();//fork进程
    if (pid < 0)//fork失败
    {
        swWarn("fork() failed. Error: %s[%d]", strerror(errno), errno);
        return -1;
    }
    if (pid > 0)//父进程
    {
        _exit(0);//中断父进程
    }
    if (setsid() < 0)//子进程,脱离控制终端
    {
        swWarn("setsid() failed. Error: %s[%d]", strerror(errno), errno);
        return -1;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/u013702678/article/details/82928917