资讯专栏INFORMATION COLUMN

PHP的pcntl进程控制教程三(多进程消费模型)

617035918 / 2026人阅读

摘要:多进程消费模型父进程等待并控制子进程的退出思路整理父进程开启后,直接获取到子进程的,然后存入数组,子进程出来后直接开启业务消费代码,然后退出,然后父进程等待子进程退出,全部退出后父进程结束代码请在模式下运行子进程的数量如果是资源类型的变量,

多进程消费模型
父进程等待并控制子进程的退出
思路整理
父进程开启后,直接获取到子进程的pid,然后存入child数组,子进程fork出来后直接开启业务消费代码,然后exit(0)退出,然后父进程pcntl_wait等待子进程退出,全部退出后父进程结束
代码
const NEWLINE = "

";

if (strtolower(php_sapi_name()) != "cli") {
    die("请在cli模式下运行");
}

$bizPath = "./childBiz/";

if (!is_dir($bizPath)) {
    @mkdir($bizPath, 0755, true);
}

$child = [];

$index = 0;
$loop = 10; //子进程的数量

//如果是资源类型的变量,父子进程会共享
//$f = fopen("./pcntl_fork_2.php", "r");

while ($index < $loop) {

    echo "当前进程:" . getmypid() . NEWLINE;

    $pid = pcntl_fork(); //fork出子进程

    //fork后父进程会走自己的逻辑,子进程从处开始走自己的逻辑,堆栈信息会完全复制给子进程内存空间,父子进程相互独立

    if ($pid == -1) { // 创建错误,返回-1

        die("进程fork失败");

    } else if ($pid) { // $pid > 0, 如果fork成功,返回子进程id

        //获取创建的子进程
        $child[$pid] = $pid;
        echo "{$pid} child create!" . microtime(true) . NEWLINE;

    } else { // $pid = 0

        // 子进程逻辑
        $sleepTime = rand(5, 18);
        sleep($sleepTime);
        $time = microtime(true);
        file_put_contents($bizPath.getmypid().".log", $time . ":" . $index . PHP_EOL, FILE_APPEND);
        exit(0);
    }
    $index++;
}

while (count($child)) {
    //阻塞等待
    $pid = pcntl_wait($status);
    $time = microtime(true);
    file_put_contents("./father.log", $time . ":" . $pid . ":" . $status . PHP_EOL, FILE_APPEND);
    if ($pid > 0) {
        unset($child[$pid]);
    }
    if ($pid == -1) {
        unset($child);
    }
//    foreach ($child as $k => $pid) {
//        //不阻塞循环判断 WNOHANG表示如果没有子进程退出立刻返回
//        $res = pcntl_waitpid($pid, $status, WNOHANG);
//        $time = microtime(true);
//        file_put_contents("./father.log", $time . ":" . $pid . ":" . $res . ":" . $status . PHP_EOL, FILE_APPEND);
//        if (-1 == $res || $res > 0) {
//            unset($child[$k]);
//        }
//    }
}

//fclose($f);
//主进程退出
exit(0);

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/28820.html

相关文章

  • PHPpcntl进程控制教程一(pcntl_fork)

    摘要:说明函数创建一个子进程,这个子进程仅进程号和父进程号与其父进程不同。返回值成功时,在父进程执行线程内返回产生的子进程的,在子进程执行线程内返回。失败时,在父进程上下文返回,不会创建子进程,并且会引发一个错误。 pcntl 简介 PHP的进程控制支持实现了Unix方式的进程创建, 程序执行, 信号处理以及进程的中断。 进程控制不能被应用在Web服务器环境,当其被用于Web服务环境时可能会...

    LeexMuller 评论0 收藏0
  • PHPpcntl进程控制教程二(pcntl_wait)

    摘要:简介来源官方等待或返回的子进程状态函数刮起当前进程的执行直到一个子进程退出或接收到一个信号要求中断当前进程或调用一个信号处理函数。子进程使用的所有系统资源将被释放。子进程已经退出并且其状态未报告时返回。 pcntl_wait 简介 # 来源官方 pcntl_wait — 等待或返回fork的子进程状态 int pcntl_wait ( int &$status [, int $op...

    MartinDai 评论0 收藏0
  • 基于Swoole和Redis实现并发队列处理系统

    摘要:大家知道,一个消息队列处理系统主要分为两大部分消费者和生产者。任务系统实时的对任务队列进行,出来一个任务就一个子进程,由子进程完成具体的任务逻辑。新的设计为了解决并发的问题,我们计划做一个更加高效强壮的队里处理系统。 背景 由于PHP不支持多线程,但是作为一个完善的系统,有很多操作都是需要异步完成的。为了完成这些异步操作,我们做了一个基于Redis队列任务系统。 大家知道,一个消息队列...

    booster 评论0 收藏0
  • PHP玩转进程之二 — 进程PHPServer

    摘要:代码实现启动启动流程见流程,主要包括守护进程保存注册信号处理器创建多进程这部分。模拟调度实际用实现捕获信号其中,会在每次调度过程中,捕获信号并执行注册的信号处理器。 首发于 樊浩柏科学院 经过 用 PHP 玩转进程之一 — 基础 的回顾复习,我们已经掌握了进程的基础知识,现在可以尝试用 PHP 做一些简单的进程控制和管理,来加深我们对进程的理解。接下来,我将用多进程模型实现一个简单的...

    stormjun 评论0 收藏0
  • Swoole-2.1.2 进程池模块使用

    摘要:在版本中我们将的进程管理模块封装成了类,现在可以在代码中使用的进程管理器了。提供的进程管理器来自于,经过大量生产项目验证,稳定性和健壮性都非常高。三任务投递进程管理器自带了消息队列和消息投递的支持。 在Swoole-2.1.2版本中我们将Server的进程管理模块封装成了PHP类,现在可以在PHP代码中使用Swoole的进程管理器了。 在实际项目中经常需要写一些长期运行的脚本,如基于r...

    ZoomQuiet 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<