Swoole是有本身的一個進程管理模塊,用來替代PHP的pcntl擴展,須要注意Process進程在系統是很是昂貴的資源,建立進程消耗很大,另外建立的進程過多會致使進程切換開銷大幅上升。數組
函數原型:swoole
Swoole\Process::__construct(callable $function, $redirect_stdin_stdout = false, $create_pipe = true)
$function
,子進程建立成功後要執行的函數,底層會自動將函數保存到對象的callback屬性上。若是但願更改執行的函數,可賦值新的函數到對象的callback屬性$redirect_stdin_stdout
,重定向子進程的標準輸入和輸出。啓用此選項後,在子進程內輸出內容將不是打印屏幕,而是寫入到主進程管道。讀取鍵盤輸入將變爲從管道中讀取數據。默認爲阻塞讀取。$redirect_stdin_stdout
後,此選項將忽略用戶參數,強制爲true。若是子進程內沒有進程間通訊,能夠設置爲 false。swoole建立多進程很簡單:new Swoole\Process('callback_function')
就能夠了,好比我要同時建立6個進程,就for 循環6次就能夠了。
假設前臺給後臺三組任務要求後臺去執行,每一個任務大概須要執行一秒的時間,咱們利用多進程的形式去實現,讓時間可以縮短。
for ($i = 0; $i < 6; $i++) {#建立了3個子進程 $process = new Swoole\Process(function ($process) { sleep(1); echo PHP_EOL . posix_getpid() . PHP_EOL;#獲取子進程PID }, false, true); $process->start();
若是是很是簡單的多進程執行任務,那麼進程間就不須要通信了,實際狀況下,不少業務是須要通信的,好比,發郵件,若是自進程發送失敗了,那麼是要通知主進程的等等。異步
swoole_process
進程間支持2種通訊方式:函數
半雙工: 數據單向流動, 一端只讀, 一端只寫。
同步 vs 異步: 默認爲同步阻塞模式, 可使用 swoole_event_add()
添加管道到 swoole 的 event loop
中, 實現異步IOoop
管道通訊是swoole_process
默認的一種通訊方式。固然咱們也能夠在實例化的時候經過參數來設定:學習
$process = new Swoole\Process('callback_function', false, true);
若是咱們打印$process
會發現,每次建立一個進程後,就會隨之建立一個管道,主進程想和哪個進程通訊,就向那個進程的管道寫入/讀取數據。spa
管道有2個方法,分別來寫入數據,和讀取數據。3d
$process->write('數據');#寫入數據
$process->read()#讀取數據
管道通信方式一:unix
$worker = []; for ($i = 0; $i < 3; $i++) { $process = new Swoole\Process(function ($process) { var_dump('子進程:' . $process->read()); sleep(1); $process->write('子進程數據'); echo PHP_EOL . posix_getpid() . PHP_EOL; }, false, true); $pid = $process->start(); $worker[$pid] = $process;//把相應的進程放到同一個數組當中 $process->write('主進程數據'); // var_dump($process->read());//同步阻塞 } foreach ($worker as $w) { var_dump('主進程:' . $w->read()); }
管道通信方式二:code
for ($i = 0; $i < 3; $i++) { $process = new Swoole\Process(function ($process) { var_dump('子進程:' . $process->read()); sleep(1); $process->write('子進程數據'); echo PHP_EOL . posix_getpid() . PHP_EOL; }, false, true); $pid = $process->start(); $process->write('主進程數據'); // 異步監聽管道中的數據,讀事件監聽,當管道可讀時觸發 swoole_event_add($process->pipe, function ($pipe) use ($process) { var_dump('主進程:' . $process->read()); }); // var_dump($process->read());//同步阻塞 }
消息隊列:
swoole 中使用消息隊列:
步驟:
啓用消息隊列做爲進程間通訊:
bool swoole_process->useQueue(int $msgkey = 0, int $mode = 2);
投遞數據到消息隊列中:
bool swoole_process->push(string $data);
從隊列中提取數據
string swoole_process->pop(int $maxsize = 8192);
案例:
for ($i = 0; $i < 3; $i++) { $process = new Swoole\Process(function ($process) { var_dump('子進程:' . $process->pop()); // $process->push('hello 主進程');#推送到主進程 }); $process->useQueue(1, 2 | swoole_process::IPC_NOWAIT);//啓用消息隊列,爭搶模式,非阻塞,可能會被任意一個子進程接收到 $pid = $process->start(); $process->push('hello 子進程');#推送到子進程,不能當作管道使用 // echo '主進程消息:' . $process->pop() . PHP_EOL; }
謝謝你們耐心觀看,但願對您有所幫助,也但願你們提供下不一樣的意見,找到更有效的方式來完成,共同窗習,謝謝!