swoole深入學習 4 process

2022-03-27 19:35:14 字數 4897 閱讀 3040

swoole-1.7.2增加了乙個程序管理模組,用來替代php的pcntl擴充套件。pcntl是php新增的乙個多程序擴充套件,用來實現多程序,但是有很多不完善的地方,swoole 就完善了這些地方,而且使得使用非常簡單。

swoole建立多程序很簡單:new swoole\process('callback_function')就可以了。

比如我要同時建立10個程序,就for 迴圈10次就可以了。

for($i=0; $i<=10 ; $i++)

非常簡單。

來個具體的例子,我們對比下普通的模式和多程序模式的時間速度區別:

多程序下併發3次,每次迴圈1億次。和普通模式下。

<?php 

echo time() .php_eol ;

$worker_num = 3;//建立的程序數

for ($i=0; $i < $worker_num ; $i++)

function callback_function($worker)

echo time() .php_eol;

}

看下列印的時間, 算最大的時間,總共用了8秒。

➜  swoole git:(master) ✗ php test.php 

1481791259 #開始時間,沒有被阻塞。

➜ swoole git:(master) ✗

1481791267 #

1481791267

1481791267

具體的資源占用:

$ time php test.php  

0.04s user

0.02s system

50% cpu

0.129 total

再看下普通迴圈模式:

<?php 

echo time() .php_eol;

for($i=0;$i<100000000;$i++){}

for($i=0;$i<100000000;$i++){}

for($i=0;$i<100000000;$i++){}

echo time() .php_eol;

看下列印時間,用了16秒。

1481791591

1481791607

具體的資源占用:

time php test.php  

15.09s user

0.11s system

96% cpu

15.720 total

如果是非常簡單的多程序執行任務,那麼程序間就不需要通訊了,實際情況下,很多業務是需要通訊的,比如,發郵件,如果自程序傳送失敗了,那麼是要通知主程序的等等。

再看程序間通訊之前,先看下 swoole\process 的幾個引數:

swoole\process(mixed $function, $redirect_stdin_stdout = false, $create_pipe = true);
它有三個引數:

$function:子程序建立成功後要執行的函式

$redirect_stdin_stdout:重定向子程序的標準輸入和輸出。 設定為true,則在程序內echo將不是列印螢幕,而是寫入到管道,讀取鍵盤輸入將變為從管道中讀取資料。 預設為false,阻塞讀取。

$create_pipe:是否建立管道,啟用$redirect_stdin_stdout後,此選項將忽略使用者引數,強制為true 如果子程序內沒有程序間通訊,可以設定為false。

swoole_process程序間支援3種通訊方式:

管道通訊

管道通訊是swoole_process預設的一種通訊方式。當然我們也可以在例項化的時候通過引數來設定:

$process = new swoole\process('callback_function', false, true);
這樣就建立了乙個管道通訊程序。我們列印下$process這個物件的值:

var_dump($process)

object(swoole_process)#1 (3)

裡面有個字段pipe是管道id,還有乙個pid是程序id,所以:

每次建立乙個程序後,就會隨之建立乙個管道,主程序想和哪乙個程序通訊,就向那個程序的管道寫入/讀取資料。
管道有2個方法,分別來寫入資料,和讀取資料。

write()  和  read()
來個例子,看下如何通過管道通訊

<?php 

/** * process 管道通訊

* user: yangyi

* date: 2016/12/9

* time: 17:10

*///程序數量

$worker_num = 2;

$workers = ;

for ($i = 0; $i < $worker_num; $i++)

// 主程序,通過管道給子程序傳送資料

foreach ($workers as $pid => $process)

//子程序執行的**函式

function callback_function($worker)

執行看下效果:

$ php process_pipe.php

from master: hello worker[6759]

from worker: hello master , this pipe is 4; this pid is 6759

from master: hello worker[6760]

from worker: hello master , this pipe is 6; this pid is 6760

注意 主程序和子程序中的read()不能一開始都讀,得寫反。不然管道中沒資料,就會阻塞住了。

所以一般的順序是:

master-->write()

work-->read()

work-->write()

master-->read()

這樣才能有序的使用通道,才不會被阻塞。而且是一對一的,write 2 次,也要read 2次,先write先read。

第二個引數$redirect_stdin_stdout說,設定為 true ,子程序會將 echo 寫入到主管道。我把上面的**改一下,看下輸出結果是啥。

$process = new swoole\process('callback_function', true, true);
緊緊改動了這一行,再看下:

//程序數量

$worker_num = 2;

$workers = ;

for ($i = 0; $i < $worker_num; $i++)

// 主程序,通過管道給子程序傳送資料

foreach ($workers as $pid => $process)

//子程序執行的**函式

function callback_function($worker)

執行下輸出結果為:

$ php test.php

from worker: from master: hello worker[9251]

from worker: from master: hello worker[9252]

來分析下,因為$redirect_stdin_stdout為true,所以子程序中echo的內容就到了主管道裡面,而不是列印在螢幕上,所以,主程序從管道裡讀到的內容,就是子程序中echo的內容。 

也就造成了上面的輸出結果。

那麼如何使子程序中的第二個write,能被主程序讀到呢?很簡單,在主程序中在 read() 一次就可以了:

// 主程序,通過管道給子程序傳送資料 

foreach ($workers as $pid => $process)

再看下列印結果:

from worker: from master: hello worker[9328]

from worker: hello master , this pipe is 4; this pid is 9328

from worker: from master: hello worker[9329]

from worker: hello master , this pipe is 6; this pid is 9329

訊息佇列

swoole程序通訊還有第二種方式就是「訊息佇列」,這個訊息佇列其實就是linux系統裡面的msgqueue

swoole提供了2個方法,來實現訊息佇列的通訊。

pop() 和 push()

swoole深入學習 1 swoole初始

swoole在php圈火了這麼久,從2年前我用node寫socket聊天伺服器的時候就火了,那時候,經常有類似的文章php swoole完爆nodejs之類的文章來吸引眼球,先不說它的好與壞,單單說他的出現,確實給php注入了一股新的活力。首先,php是單程序的,沒法在乙個程式塊中使用多程序來處理乙...

UIApplication深入學習

新建乙個任意型別的ios應用工程,加入我們在class prefix輸入是tc,我們可以看到工程中生成乙個類 在main函式中,autoreleasepool 函式中 說明 當應用程式將要入非活動狀態執行,在此期間,應用程式不接收訊息或事件。比如來 了。說明 當應用程式入活動狀態執行,這個剛好跟上面...

深入學習CSS

什麼是css?在之前的這篇文章中已經介紹了初步的介紹,詳細請看 div加css進一步講解了css中的內容,先總結如下圖 其實在實際開發中,我們通常採用是外部樣式的匯入,這樣做的好處是對於很對有同樣設計樣式的頁面可以實現樣式的共享,這樣我們不僅僅可以節省了大量的時間,並且也方便我們可以靈活的呼叫的樣式...