参考文献

官方多进程文档:https://wiki.swoole.com/#/process/process?id=__construct

php卡死问题定位:https://course.swoole-cloud.com/article/2

代码下载:https://github.com/mailjobblog/dev_swoole/tree/master/210524_process_more

多进程问题

为什么要 wait 结束子进程

每个子进程结束后,父进程必须都要执行一次 wait() 进行回收,否则子进程会变成僵尸进程,会浪费操作系统的进程资源。

如果子进程不写入管道数据可以吗

不可以。主进程会处于阻塞状态,等待子进程的管道数据。

演示demo

场景描述

定义两个进程,一个发送邮件的进程,一个发送短信的进程。swoole创建两个进程后,采用管道进行通信,然后由父进程读取管道的数据,进行返回展示。

代码实现

<?php
// 程序开始时间
$start = microtime(true);

// 数据定义
$info = array(
    "status" => 1,
    "mailto" => "666@qq.com",
    "smsto" => "999999999"
);

/**
 * 开启两个进程
 *
 * 发送邮件进程 + 发送短信进程
 */
$mail_process = new Swoole\Process('sendMail',true);
$mail_process->start();// fork 一个子进程

$sms_process = new Swoole\Process('sendSMS',true);
$sms_process->start();

/**
 * 读取管道的内容
 */
echo $mail_process->read();
echo PHP_EOL;
echo $sms_process->read();
echo PHP_EOL;

// 回收结束调用的子进程
Swoole\Process::wait(true);// true 为阻塞
Swoole\Process::wait(true);

// 程序结束时间
$end = microtime(true);
echo "用时:".($end - $start).PHP_EOL;

/**
 * 发送邮件进程程序
 */
function sendMail(Swoole\Process $worker){
    global $info;

    // 模拟业务执行
    sleep(2);

    // 写入到管道
    $worker->write("子进程的pid:".$worker->pid."......邮件发送地址:".$info['mailto']);
}

/**
 * 发送短信进程程序
 */
function sendSMS(Swoole\Process $worker){
    global $info;
    if($info['status']==1){
        sleep(3);
        echo "短信息发送地址:".$info['smsto'];
    }
}