摘要:當子進程都完成了,主進程開始繼續業務。是子進程的句柄子進程句柄向自己管道里寫內容子進程句柄從自己的管道里面讀取信息這里是子進程哦貼上運行結果喔,通訊是這樣的。我們再看看創建進程時第二個參數的說明,重定向子進程的標準輸入和輸出。
進程管理模塊
介紹看這里 swoole的process
大家可以先看看自己的swoole版本,在命令行里面敲
php --ri swoole
更多的php命令行使用,大家學習 php命令行參數
ok 我們直奔主題
怎么用
不多說,直接上代碼
start(); echo PHP_EOL . $pid;// } function callback_function_we_write(swoole_process $worker){ echo PHP_EOL; var_dump($worker); echo PHP_EOL; }
運行結果如下
5445 object(swoole_process)#1 (3) { ["pipe"]=> int(3) ["callback"]=> string(26) "callback_function_we_write" ["pid"]=> int(5445) } 5446 object(swoole_process)#2 (3) { ["pipe"]=> int(5) ["callback"]=> string(26) "callback_function_we_write" ["pid"]=> int(5446) }
可以看到,我們使用 new swoole_process 創建進程,這里需要一個參數,也就是回調函數
當我們使用 $process->start()執行后,返回這個進程的pid ,也就是 $pid.
此時子進程啟動,調用回調函數,并傳一個參數 也就是 swoole_process 類型的 $worker
我故意輸出了 $worker 看看里面有什么,結果有三個屬性
pipe 進程的管道id 這個等說道進程間通信的時候再聊
pid 就是當前子進程的 pid 啦
callback 這個是我們自己寫的回調函數名
到這里,我們就可以用多進程玩耍了,
比如,我們可以測試多進程的運行速度
start(); } function callback_function_we_write(swoole_process $worker){ for($i=0;$i<100000000;$i++){} echo PHP_EOL . time() ; }
我本機運行結果
1435563435 // 開始時間
1435563438 //進程1 結束時間
1435563440 //進程2 結束時間
1435563440 //進程3 結束時間
算三次 用了5s (其實一般是4s)
再玩一次
我本機運行結果
1435563704
1435563712這次用了8s
做了這些,我想說明一個問題
并不是說 單進程 要花8s 做完的活,我們用3個進程就能將時間縮小三倍了
嘛,因為這是我以前的誤區
多進程還可以這樣玩
start(); sleep(2); } while(1){ $ret = swoole_process::wait(); if ($ret){// $ret 是個數組 code是進程退出狀態碼, $pid = $ret["pid"]; echo PHP_EOL."Worker Exit, PID=" . $pid . PHP_EOL; }else{ break; } } function methodOne(swoole_process $worker){// 第一個處理 echo $worker->callback .PHP_EOL; } function methodTwo(swoole_process $worker){// 第二個處理 echo $worker->callback .PHP_EOL; } function methodThree(swoole_process $worker){// 第三個處理 echo $worker->callback .PHP_EOL; }我多加的sleep是為了運行時看得更清楚,你也可以去掉
這里我使用了 swoole_process::wait() 詳解
目的是當子進程結束后,主進程能夠知道。我們來想一個情景
過節了,媽媽要做飯,一看廚房里缺了 油,鹽,糖,味精,十三香。于是吩咐兒子去小賣部買點回來。廚房這邊也不能閑著,老媽要繼續洗菜,切菜。等到調料買回來了,菜也洗好,切好了,開始炒,這邊炒好了一個菜,就要立刻送到餐桌上。這個情景里面,顯然使用了多進程,并且各進程做的不是同樣的事情。當子進程都完成了,主進程開始繼續業務。
現在有了一個問題,就拿上面的情景來說,兒子去買調味料,如果發現鹽沒有了,或者錢不夠了怎么辦,如何與媽媽聯系呢? 這就是下面要說的 進程間的通信
進程間的通信Process 的通信方式有兩種
管道
swoole_process->write(string $data);
swoole_process->read(int $buffer_size=8192);消息隊列
swoole_process->useQueue();
swoole_process->push(string $data);
swoole_process->pop(int $maxsize = 8192);我們先說說管道
管道通訊這里我們要再次的提及進程的創建 new swoole_process
大家請看這里 進程的創建
第一個參數是回調函數,不說了
第二個參數含義等會我會結合例子來說
第三個參數是默認的 true,意思是創建管道,大家還記得回調函數里我特意將$worker輸出看到的內容嗎?object(swoole_process)#1 (3) { ["pipe"]=> int(3) ["callback"]=> string(26) "callback_function_we_write" ["pid"]=> int(5445) }關鍵是這里的 pipe 這個就是本進程的管道id
我們可以這樣理解每次創建一個進程后,就會隨之創建一個管道,主進程想和哪一個進程通信,就向那個進程的管道寫入/讀取數據。
ok,我們看看代碼
start(); $workers[$pid] = $process;//將每一個進程的句柄存起來 } // 這里是主進程哦。 foreach($workers as $pid => $process){// $process 是子進程的句柄 $process->write("hello worker[$pid] ");//子進程句柄向自己管道里寫內容 $process->write($data); echo "From Worker: ".$process->read();//子進程句柄從自己的管道里面讀取信息 $process->read(); echo PHP_EOL.PHP_EOL; } function workerFunc(swoole_process $worker){//這里是子進程哦 $recv = $worker->read(); echo PHP_EOL. "From Master: $recv "; //send data to master $worker->write("hello master , this pipe is ". $worker->pipe ."; this pid is ".$worker->pid." "); sleep(2); $worker->exit(0); }貼上運行結果
From Master: hello worker[8205] From Worker: hello master , this pipe is 3; this pid is 8205 From Master: hello worker[8206] From Worker: hello master , this pipe is 5; this pid is 8206喔,通訊是這樣的。
首先 將所有的子進程的句柄都存到 主進程的一個數組里,數組下標就是pid。
當主進程想和哪個進程通訊,就使用那個句柄向對應管道里面 寫/讀 數據,這樣就實現了進程間的通訊。接著,我們稍微改一下,看看運行效果
$redirect_stdout = true;// 重定向輸出 注意 這次我改成 true 了,其他沒變 $worker_num = 2;//進程數量 $workers = [];//存放進程用的 for($i = 0; $i < $worker_num; $i++){ $process = new swoole_process("workerFunc",$redirect_stdout ); $pid = $process->start(); $workers[$pid] = $process;//將每一個進程的句柄存起來 } // 這里是主進程哦。 foreach($workers as $pid => $process){// $process 是子進程的句柄 $process->write("hello worker[$pid] ");//子進程句柄向自己管道里寫內容 $process->write($data); echo "From Worker: ".$process->read();//子進程句柄從自己的管道里面讀取信息 $process->read(); echo PHP_EOL.PHP_EOL; } function workerFunc(swoole_process $worker){//這里是子進程哦 $recv = $worker->read(); echo PHP_EOL. "From Master: $recv "; //send data to master $worker->write("hello master , this pipe is ". $worker->pipe ."; this pid is ".$worker->pid." "); sleep(2); $worker->exit(0); }輸出結果
From Worker: From Master: hello worker[8007] From Worker: From Master: hello worker[8008]誒,不一樣了有沒有。我們再看看創建進程時第二個參數的說明
$redirect_stdin_stdout,重定向子進程的標準輸入和輸出。 啟用此選項后,在進程內echo將不是打印屏幕,而是寫入到管道。讀取鍵盤輸入將變為從管道中讀取數據。 默認為阻塞讀取。
我來說明一下,因為創建的時候指定了true,子進程中echo的內容就到了管道里面,而不是打印在屏幕上(這一點類似于php的ob緩存機制,大家想象一下)
消息隊列
前面說了,進程的通訊是通過從管道里面讀/寫數據實現的,而 子進程 里 echo 的內容被 重定向到管道里面了,所以,主進程從管道里讀到的內容,就是 子進程中 echo 的 內容。
也就造成了上面的 輸出結果。我先來個鏈接 利用PHP操作Linux消息隊列完成進程間通信
重點是這個文章里面的兩個鏈接文章啊,大家等會看看
還有一個命令ipcs -q 查看當前的消息隊列
這部分 下次討論
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/20990.html
摘要:不多說,上代碼這段代碼出自消息隊列我想說五個點的創建默認是創建的管道,當想用消息隊列時,記得把參數設成其實我發現不寫也行要在的之前調用,方法默認是阻塞的一定一定要寫這里坑死不少人還有第五點注意事項,我接下來重點說,因為這個點卡了我好久。 不多說,上代碼
摘要:原先用的多線程實現的支付結果回調服務,在后期運行中出現了服務停止的問題,在學習的過程中,發現可以用的進程管理模塊實現多線程的功能,并且使用定時器功能實現進程監控在子進程退出的時候進行重啟。 原先用PHP的Pthread多線程實現的支付結果回調服務,在后期運行中出現了服務停止的問題,在學習swoole的過程中,發現可以用swoole的Process進程管理模塊實現多線程的功能,并且使用s...
摘要:消息隊列更常見的用途是主進程分配任務,子進程消費執行。子進程前面加了個,這是為了防止父進程還未往消息隊列中加入內容直接退出。 前面幾節都是講解pcntl擴展實現的多進程程序。本節給大家介紹swoole擴展的swoole_process模塊。 swoole多進程 swoole_process 是swoole提供的進程管理模塊,用來替代PHP的pcntl擴展。 首先,確保安裝的swoole...
摘要:在中的應用官網源碼解讀號外號外歡迎大家我們開發組定了一個就線下聚一次的小目標上一篇源碼解讀反響還不錯不少同學推薦再加一篇講解一下中使用到的功能幫助大家開啟的實戰之旅服務器開發涉及到的相關技術領域的知識非常多不日積月累打好基礎是很難真正 date: 2017-12-14 21:34:51title: swoole 在 swoft 中的應用 swoft 官網: https://www.sw...
摘要:配合模塊,創建的子進程可以異步的事件驅動模式。默認為阻塞讀取。函數用于將一個加入到的事件監聽中。為事件類型的掩碼,可選擇關閉開啟可讀可寫事件,如,,或者。在程序中使用,可以理解為在進程中將此注冊到事件中。 Process Process是swoole內置的進程管理模塊,用來替代PHP的pcntl擴展。 swoole_process支持重定向標準輸入和輸出,在子進程內echo不會打印屏...
閱讀 2574·2021-10-19 11:41
閱讀 2415·2021-09-01 10:32
閱讀 3377·2019-08-29 15:21
閱讀 1756·2019-08-29 12:20
閱讀 1161·2019-08-29 12:13
閱讀 599·2019-08-26 12:24
閱讀 2520·2019-08-26 10:26
閱讀 827·2019-08-23 18:40