workerman笔记-php创建守护进程

1354 查看

使用函数

pcntl_fork();//创建子进程
posix_setsid();//设置当前进程为进程组长

posix_getpid();//获取进程id

例子

workerman中将进程

/**
 * Run as deamon mode.
 *
 * @throws Exception
 */
protected static function daemonize()
{
    if (!self::$daemonize) {
        return;
    }
    /**
     * 重设文件权限掩码
     * 子进程从父进程继承了文件权限
     * 若子进程不涉及到文件创建,可取消
     */
    umask(0);
    $pid = pcntl_fork();//创建子进程
    if (-1 === $pid) {
        throw new Exception('fork fail');
    } elseif ($pid > 0) {
        exit(0); //父进程退出
    }
    /**
     * 更改子进程为进程组长
     * 使子进程摆脱父进程控制
     */
    if (-1 === posix_setsid()) {
        throw new Exception("setsid fail");
    }
    // Fork again avoid SVR4 system regain the control of terminal.
    $pid = pcntl_fork();
    if (-1 === $pid) {
        throw new Exception("fork fail");
    } elseif (0 !== $pid) {
        exit(0);
    }
}

其他说明

基本概念

守护进程:Linux中的后台服务进程。它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。守护进程常常在系统引导装入时启动,在系统关闭时终止。

进程组:是一个或多个进程的集合。进程组有进程组ID来唯一标识。除了进程号(PID)之外,进程组ID也是一个进程的必备属性。每个进程组都有一个组长进程,其组长进程的进程号等于进程组ID。且该进程组ID不会因组长进程的退出而受到影响。

会话周期:会话期是一个或多个进程组的集合。通常,一个会话开始于用户登录,终止于用户退出,在此期间该用户运行的所有进程都属于这个会话期。

创建流程

  1. fork子进程,父进程退出

  2. 更改子进程为组长进程

  3. 改变当前目录为根目录(chdir())

  4. 重设文件权限掩码

  5. 关闭文件描述符

  6. 守护进程退出,处理SIGCHLD信号

信号处理

//TODO

参考资料

PHP实现守护进程