使用步骤
1. 创建子进程对象
// 普通形式
$process = new swoole_process('callback_function', true);
// oop形式
swoole_process::__construct(callable $function, $redirect_stdin_stdout = false, $create_pipe = true);
// 启用命名空间的方式
Swoole\Process::__construct(callable $function, $redirect_stdin_stdout = false, $create_pipe = true)
这里需要注意的是,第二、第三个参数要填false或者0,表示不启用管道模式。
2. 启用消息队列
swoole_process->useQueue(int $msgkey = 0, int $mode = 2);
useQueue
方法接受2
个可选参数。
$msgkey
是消息队列的key,默认会使用ftok(FILE, 1)
作为KEY
$mode
通信模式,默认为2
,表示争抢模式
,所有创建的子进程都会从队列中取数据
如果创建消息队列失败,会返回false
。可使用swoole_strerror(swoole_errno())
得到错误码和错误信息。
使用模式2
后,创建的子进程无法进行单独通信,比如发给特定子进程。
$process
对象并未执行start
,也可以执行push/pop
向队列推送/提取数据
非阻塞模式
$process->useQueue($key, $mode | swoole_process::IPC_NOWAIT);
在非阻塞模式下,队列已满调用push
方法、队列已空调用pop
方法时将不再阻塞立即返回。
3. 启动子进程
function swoole_process->start()
4. 投递数据到消息队列
Process->push(string $data);
5. 从消息对垒提取数据
string Process->pop(int $maxsize = 8192);
6. 退出子进程
Process->exit(int $status=0);
子进程退出后,在父进程中执行Process::wait
可以得到子进程退出的事件和状态码。
完整例子
<?php
// 1.定义子进程对象数组
$workers = [];
// 2.最大进程数
$workers_num = 2;
// 3.批量创建子进程
for($i = 0; $i < $workers_num; $i++){
// 4.创建子进程
$process = new swoole_process('doProcess', false, false);
// 5.开启消息队列
$process->useQueue();
// 6.启动子进程
$pid = $process->start();
// 7.把子进程对象加到workers数组
$workers[$pid] = $process;
}
// 子进程执行函数
function doProcess(swoole_process $process){
// 1.从消息队列获取数据
$recv = $provess->pop();
// 2.从主进程获取到的数据
echo "从主进程获取到的数据是: $recv \n";
sleep(5);
// 3.退出子进程
$process->exit();
}
// 主进程向 子进程添加数据
foreach($workers as $pid=> $process){
$process->push("hello,子进程$pid \n");
}
// 等待子进程结束,回收资源
for($i = 0; $i < $workers_num; $i++){
// 这里需要注意,当子进程exit之后,父进程一定要使用wait回收进程,否则将会成为僵尸进程
// 1.等待子进程结束
$ret = swoole_process::wait();
// 2.从数组里移除子进程
unset($workers[$pid]);
echo "子进程$pid退出";
}
这里需要特别注意:当子进程exit之后,父进程一定要使用wait回收进程,否则将会成为僵尸进程。