参考文献

官方多进程文档: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创建两个进程后,采用管道进行通信,然后由父进程读取管道的数据,进行返回展示。

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<?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'];
}
}