swoole-Process多进程执行CURL任务
案例一:
备注:用时一秒同时执行多个CURL获取内容
<?php use Swoole\Process; echo 'Start Time:'.date("Y-m-d H:i:s",time()); $workers = []; $urls = [ 'https://www.baidu.com', 'https://www.sina.com.cn', 'https://www.qq.com', 'https://www.taobao.com' ]; for($i=0;$i<4;$i++){ //子进程 $process = new Process(function ($workers) use ($i,$urls) { //curl $content = curlData($urls[$i]); $workers->write($content.PHP_EOL); },true); $pid = $process->start(); $workers[$pid] = $process; } //读取 foreach($workers as $process){ echo $process->read(); } /** * 模拟请求URL的内容 1s */ function curlData($url){ //curl File_get_contents $url = file_get_contents($url); sleep(1); return $url.PHP_EOL; } echo 'Start End:'.date("Y-m-d H:i:s",time());
案例二:
<?php use Swoole\Process; //执行方案一 $is_value = 2; if($is_value == 1){ /** * 方案一:单进程发送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); }else{ /** * 方案二:多进程发送10封邮件 * swoole_process::__construct(callable $function, $redirect_stdin_stdout = false, $create_pipe = true); * $redirect_stdin_stdout,重定向子进程的标准输入和输出。启用此选项后,在子进程内输出内容将不是打印屏幕, * 而是写入到主进程管道(例如用echo打印的内容也写入管道).读取键盘输入将变为从管道中读取数据。默认为阻塞读取。 * $create_pipe,是否创建管道,启用$redirect_stdin_stdout后,此选项将忽略用户参数,强制为true。 * 如果子进程内没有进程间通信,可以设置为 false */ $start_time = microtime(true); $workers = array(); for ($i=0;$i<10;$i++){ $process = new swoole_process(function($worker){ $i = $worker->read(); $res = sendEmail(rand(11111111,99999999)."@qq.com"); $worker->write("第{$i}个邮件发送完毕!状态:".$res.PHP_EOL); },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 sendEmail($email){ sleep(1); //发送邮件 //返回发送的结果状态 $str = 'send email:'.$email.'成功'; return $str; }