swoole多进程任务
swoole发展很快版本迭代也很快,是弥补了PHP的缺点,提升了PHP的性能,唯一的不足就是文档太差了点,很多想入门的人在官方文档并不能够顺利的进行学习。我也是开始研究swoole的一些知识,下面是总结的swoole多进程的一些知识点。
swoole多进程例子1:
<?php
//单进程发送10封邮件
/*$start_time = microtime(true);
for ($k = 0;$k < 10;$k ++)
{
sleep(1);
$res = sendEmail(rand(11111111,99999999)."@qq.com");
echo $res.$k.PHP_EOL;
}
$end_time = microtime(TRUE);
echo sprintf("use time:%.3f s\n", $end_time - $start_time);
exit;*/
//多进程发送10封邮件
$start_time = microtime(true);
$workers = array();
for ($i=0;$i<10;$i++){
/**
* swoole_process::__construct(callable $function, $redirect_stdin_stdout = false, $create_pipe = true);
* $redirect_stdin_stdout,重定向子进程的标准输入和输出。启用此选项后,在子进程内输出内容将不是打印屏幕,
* 而是写入到主进程管道(例如用echo打印的内容也写入管道).读取键盘输入将变为从管道中读取数据。默认为阻塞读取。
* $create_pipe,是否创建管道,启用$redirect_stdin_stdout后,此选项将忽略用户参数,强制为true。
* 如果子进程内没有进程间通信,可以设置为 false
*/
$process = new swoole_process('getContents',true);
$pid = $process->start();
$process->write($i);
//echo $process->read().PHP_EOL; //同步阻塞读取管道数据,导致的后果就是父进程依次等待每个进程处理完并返回了内容,才走下一次循环
$workers[] = $process;
//解决方案1
//使用swoole_event_add将管道加入到事件循环中,变为异步模式
/*swoole_event_add($process->pipe, function($pipe) use($process) {
echo $rec = $process->read();
swoole_event_del($process->pipe);//socket处理完成后,从epoll事件中移除管道
});*/
}
//主进程数据结果
/**
* 解决方案2
* 原因是父进程读取子进程返回的数据的时候,是同步阻塞读取
* 此方案就解决了同步阻塞读取数据的问题,统一获取子进程的返回数据
*
*/
foreach ($workers as $process){
echo $process->read().PHP_EOL;
}
//子进程结束必须要执行wait进行回收,否则子进程会变成僵尸进程
while($ret = swoole_process::wait()){// $ret 是个数组 code是进程退出状态码,
$pid = $ret['pid'];
echo PHP_EOL."Worker Exit, PID=" . $pid . PHP_EOL;
}
$end_time = microtime(TRUE);
echo sprintf("use time:%.3f s\n", $end_time - $start_time);
function getContents(swoole_process $worker){
$i = $worker->read();
$res = sendEmail(rand(11111111,99999999)."@qq.com");
$worker->write("第{$i}个邮件发送完毕!状态:".$res.PHP_EOL);
}
function sendEmail($email){
sleep(1);
//发送邮件
//返回发送的结果状态
$str = 'send email:'.$email.'成功';
return $str;
}
附上运行截图:
单进程运行耗时:
多进程运行耗时:
对比差距还是很大,swoole确实节约了很多时间。