多进程执行代码
主进程异常退出时,子进程会继续执行,完成所有任务后退出
use Swoole\Process;
for ($n = 1; $n <= 3; $n++) {
// 实例化一个进程指定执行程序,回调参数为当前进程对象
$process = new Process(function ($process) use ($n) {
echo 'Child #' . $process->pid . " start and sleep {$n}s" . PHP_EOL;
sleep($n);
echo 'Child #' . $process->pid . ' exit' . PHP_EOL;
});
// 启动子进程,子进程会继承父进程的内存和文件句柄,子进程在启动时会清除从父进程继承的EventLoop、Signal、Timer
// 执行fork系统调用,启动子进程。在Linux系统下创建一个进程需要数百微秒时间。
$pid = $process->start();
// 设置进程执行在那几个cpu上
// $process->setAffinity(array());
// 设置进程的优先级,值越小优先级越高(-20到20)
// 修改优先级的类型
//$whichs = [
// PRIO_PROCESS 进程
// PRIO_PGRP 进程组
// PRIO_USER 用户进程
//];
//$process->setAffinity(PRIO_PROCESS, $priority);
// 获取进程的优先级
//$process->getPriority(PRIO_PROCESS);
}
for ($n = 3; $n--;) {
// 回收结束运行的子进程,阻塞等待,子进程结束后如果父进程不回收子进程将变成僵尸进程,影响资源
// 结果包含子进程的PID、退出状态码、被哪种信号KILL
$status = Process::wait(true);
echo "Recycled #{$status['pid']}, code={$status['code']}, signal={$status['signal']}" . PHP_EOL;
}
echo 'Parent #' . getmypid() . ' exit' . PHP_EOL;
多进程指定类的方法
$process = new Process(['My', 'abc']);
$pid = $process->start();
$status = Process::wait(true);
echo "Recycled #{$status['pid']}, code={$status['code']}, signal={$status['signal']}" . PHP_EOL;
多进程执行--指定回调内启用协程
可以直接在子进程的函数中使用协程 API
use Swoole\Process;
use function Swoole\Coroutine\run;
$process = new Process(function ($process) {
var_dump('PID=' . $process->pid);
for ($i = 1; $i < 5; $i++){
Swoole\Coroutine::sleep($i);
echo $i . "\n";
}
}, false, 1, true);
$process->start();
$status = Process::wait(true);
echo "Recycled #{$status['pid']}, code={$status['code']}, signal={$status['signal']}" . PHP_EOL;
父进程与子进程使用标准输入输出进行通信
子进程内输出内容将不是打印屏幕,而是写入到主进程管道。读取键盘输入将变为从管道中读取数据
use Swoole\Process;
use function Swoole\Coroutine\run;
$process = new Process(function ($process) {
var_dump('PID=' . $process->pid);
for ($i = 1; $i < 5; $i++){
echo $i . "\n";
}
}, true);
$process->start();
run(function() use($process) {
/*
将unixSocket导出为Coroutine\Socket对象,然后利用 Coroutine\socket 对象的方法进程间通讯
多次调用此方法,返回的对象是同一个
关闭导出的socket时不会影响进程原有的管道
必须在协程容器中使用
*/
$socket = $process->exportSocket();
// 一次接收所有的打印输出
echo "from children: " . $socket->recv() . "\n";
});
$status = Process::wait(true);
echo "Recycled #{$status['pid']}, code={$status['code']}, signal={$status['signal']}" . PHP_EOL;