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確實節約了很多時間。