很少說,上代碼php
<?php $workers = []; $worker_num = 2; for($i = 0; $i < $worker_num; $i++) { $process = new swoole_process('callback_function', false, false); $process->useQueue(); $pid = $process->start(); $workers[$pid] = $process; //echo "Master: new worker, PID=".$pid."\n"; } function callback_function(swoole_process $worker) { //echo "Worker: start. PID=".$worker->pid."\n"; //recv data from master $recv = $worker->pop(); echo "From Master: $recv\n"; sleep(2); $worker->exit(0); } foreach($workers as $pid => $process) { $process->push("hello worker[$pid]\n"); } for($i = 0; $i < $worker_num; $i++) { $ret = swoole_process::wait(); $pid = $ret['pid']; unset($workers[$pid]); echo "Worker Exit, PID=".$pid.PHP_EOL; }
這段代碼出自 消息隊列html
我想說五個點swoole
還有第五點注意事項,我接下來重點說,由於這個點卡了我很久。code
嘛,demo裏面只是說主進程向子進程發數據,沒有子進程向主進程發數據,我就來加上吧htm
<?php $workers = []; $worker_num = 2; for($i = 0; $i < $worker_num; $i++) { $process = new swoole_process('callback_function',false,false); $process->useQueue(); $pid = $process->start(); $workers[$pid] = $process; //echo "Master: new worker, PID=".$pid."\n"; } function callback_function(swoole_process $worker) { //echo "Worker: start. PID=".$worker->pid."\n"; //recv data from master $recv = $worker->pop(); echo "From Master: $recv\n"; $worker->push(" \n hehe \n ");//這裏子進程向主進程發送 hehe sleep(2);//注意這裏有個sleep $worker->exit(0); } foreach($workers as $pid => $process) { $process->push("hello worker[$pid]\n"); $result = $process->pop(); echo "From worker: $result\n";//這裏主進程,接受到的子進程的數據 } for($i = 0; $i < $worker_num; $i++) { $ret = swoole_process::wait(); $pid = $ret['pid']; unset($workers[$pid]); echo "Worker Exit, PID=".$pid.PHP_EOL; }
運行結果完美,我就不貼了,
我看着代碼,突然發現本身沒把sleep刪掉,而後噩夢開始了
你們把上面代碼的sleep註釋後運行看看,我這裏貼上個人運行結果隊列
From Master: hello worker[3667] From worker: hehe PHP Warning: swoole_process::push(): msgsnd() failed. Error: Invalid argument[22] in /home/sun/learn/swoole/process/demo.php on line 28 PHP Warning: swoole_process::pop(): msgrcv() failed. Error: Invalid argument[22] in /home/sun/learn/swoole/process/demo.php on line 29 From worker: PHP Warning: swoole_process::pop(): msgrcv() failed. Error: Identifier removed[43] in /home/sun/learn/swoole/process/demo.php on line 18 From Master: PHP Warning: swoole_process::push(): msgsnd() failed. Error: Invalid argument[22] in /home/sun/learn/swoole/process/demo.php on line 20 Worker Exit, PID=3668 Worker Exit, PID=3667
這就是個人報錯,我看這個錯誤,發現第一個進程是完美執行的,和預先想的同樣,錯誤出在主進程第二次發送消息到消息隊列時出現的,主進程的數據發送出錯了進程
哎呀,怎麼回事,不明白。
其實故事是這樣的
主進程建立兩個子進程,這裏沒問題
主進程向第一個子進程發數據,第一個子進程收到後向主進程回發數據,這裏也沒問題
主進程再向第二個子進程發數據,好,出問題了,
那麼 問題來了,第一個子進程作了什麼咱們不知道的事情?
請看這裏 子進程臨死前作了什麼rem
$status是退出進程的狀態碼,若是爲0表示正常結束,會繼續執行PHP的shutdown_function,其餘擴展的 清理工做get
第一個子進程臨死前把消息隊列給埋了消息隊列
換句話說,主進程再想往消息隊列裏寫東西時寫不了了,由於沒有消息隊列了。
那爲何剛開始有sleep的時候就沒事呢?
由於趁着第一個子進程睡覺的時候,主進程和第二個子進程把事情作了
那麼咱們怎麼辦?怎麼才能不讓子進程摧毀消息隊列??
把 swoole_process->exit(0) 改爲 swoole_process->exit(1)了
這是我要說的第五點
多個子進程使用消息隊列通信必定寫上 $process->exit(1)
好的,基本上遵照這五條,使用消息隊列就不會有什麼問題了。最後請記得升級本身的swoole版本,由於有些問題多是由於你的版本太老了