画江湖之 PHP 多进程开发 [实现守护进程化]

特点

  • 后台运行
  • 不受任何终端控制
  • 可以由 系统启动脚本/etc/rc.local 、crontab任务、用户shell 三种方式执行

主要实现的核心过程

如何守护进程化
1.创建子进程,终止父进程       
2.在子进程中创建新会话
3.改变工作目录(默认继承了父进程的当前工作目录)
4.重设文件创建掩码(默认继承了父进程的文件创建掩码)
5.关闭文件描述符(默认继承了父进程打开了的文件)

主要的函数

1.pcntl_fork, exit  创建子进程,退出进程
2.posix_setsid      让当前进程变为主会话
3.chdir('/')        当前工作目录改为 root 目录
4.umask(0)      改变当前的 umask 为最宽松掩码
5.fclose            关闭一个已打开的文件指针

代码段

<?php

function daemon() {
    // 1-1
    $pid = pcntl_fork();//fork一个子进程

    switch ($pid) {
    case -1:
        die('Create failed');
        break;
    case 0:
        // Child

        // 2.
        if ( ($sid = posix_setsid()) <= 0 ) {//让当前的子进程变成住会话
            die("Set sid failed.\n");
        }

        // 3.
        if (chdir('/') === false) {//把当前目录变成root目录
            die("Change dir failed.\n");
        }

        // 4.
        umask(0);//重设置文件的创建掩码

        // 5.
        fclose(STDIN);//关闭一个打开的文件指针
        fclose(STDOUT);
        fclose(STDERR);

        break;
    default:
        // Parent

        // 1-2//退出主进程
        exit;
        break;
    }
}

function fork() {
    global $childs;

    $pid = pcntl_fork();

    switch ($pid) {
    case -1:
        die('Create failed');
        break;
    case 0:
        // Child
        while (true) {
            sleep(5);
        }

        break;
    default:
        // Parent

        $childs[$pid] = $pid;
        break;
    }
}

daemon();

$childs = [];

$count = 3;

for ($i = 0; $i < $count; $i++) {
    fork();
}

while ( count($childs) ) {
    if ( ($exit_id = pcntl_wait($status)) > 0 ) {
        unset($childs[$exit_id]);
    }

    if ( count($childs) < 3 ) {
        fork();
    }
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 4
Complicated

我们现在都是 用artisan命令起一个while的程序,然后一直跑,再用定时任务执行一个shell脚本,一分钟去检测一下while还在不在,不在就把while程序拉起来

4年前 评论

@Complicated 这种方式也可以

4年前 评论
Complicated

@Krisji 这也是没办法了,,哎

4年前 评论

@Complicated 可以使用 supervisor 来管理那个进程

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!