PHP多程序併發控制的測試用例

2021-05-23 18:35:05 字數 3070 閱讀 7074

轉http://blog.s135.com/post/311/

最近遇到乙個問題,linux下的php命令列程式作為守護程序,需要從佇列檔案中讀一行資料,通過tcp協議傳送給外地的接收伺服器,再讀下一行資料,再傳送。當本地與外地的網路狀況不好時,有時候傳送一條資料所耗費的時間就較長,累積起來容易造成佇列堵塞和延遲。

於是,我準備用該php命令列程式生成多個子程序,將序列處理變成並行處理。最簡單的方法就是在php中用exec()或popen()函式將乙個shell命令列推到後台去執行,例如:

<?php

exec("/bin/sh /opt/zhangyan.sh &");

?>

最後的&表示將shell指令碼推到後台去執行。

但是這樣會有乙個問題,如果推到後台的程序太多,可能會導致伺服器系統資源耗盡而崩潰,所以必須控制程序數量。

我寫了乙個php程式(/opt/zhangyan.php)、乙個shell程式(/opt/zhangyan.sh)作為測試用例。

程式的邏輯:

1、設定/opt/zhangyan.php最多允許生成500個子程序;

2、當/opt/zhangyan.php讀取到一條資料後,將允許生成的子程序數減1(空閒程序數$p_number=500-1=499),然後將資料交給/opt/zhangyan.sh去後台處理,不等待/opt/zhangyan.sh處理結束,繼續讀取下一條資料;

3、當允許生成的子程序數減至0時(空閒程序數$p_number=0),/opt/zhangyan.php會等待1秒鐘,然後檢查後台還有多少個/opt/zhangyan.sh子程序尚未處理結束;

4、如果1秒鐘之後/opt/zhangyan.php發現後台的/opt/zhangyan.sh子程序數還是500(空閒程序數$p_number=0),會繼續等待1秒鐘,如此反覆;

5、如果/opt/zhangyan.php發現後台尚未處理結束的/opt/zhangyan.sh子程序數減少到300個了(空閒程序數$p_number=500-300=200),那麼/opt/zhangyan.php會再往後臺推送200個/opt/zhangyan.sh子程序;

/opt/zhangyan.php**如下:

<?php

function run($input)

global $p_number;

if ($p_number <= 0)

$p_number = worker_processes($p_number);

$p_number = $p_number - 1;

$out = popen("/bin/sh /opt/zhangyan.sh /"/" &", "r");

pclose($out);

function worker_processes($p_number)

$limit = 500;//允許推到後台的最大程序數

while ($p_number <= 0)

$cmd = popen("ps -ef | grep /"/opt/zhangyan.sh/" | grep -v grep | wc -l", "r");

$line = fread($cmd, 512);

pclose($cmd);

$p_number = $limit - $line;

if ($p_number <= 0)

sleep(1);//暫停1秒鐘

return $p_number;

$input = "http://blog.s135.com"; //模擬從佇列檔案中讀取到的資料

for ($i = 1; $i <= 1000; $i++)

run($input);

echo "idle process number: " . $p_number . "/n";

(/opt/zhangyan.php程式用來模擬從佇列檔案中讀取1000行資料,交給子程序/opt/zhangyan.sh去處理。)

/opt/zhangyan.sh**如下:

#!/bin/sh

echo $(date -d "today" +"%y-%m-%d %h:%m:%s") $1 >> /opt/zhangyan.log

sleep_time=$(expr $random % 4 + 1)

sleep $sleep_time

(/opt/zhangyan.sh指令碼用來模擬向外地接收伺服器傳送資料。其中的$(expr $random % 4 + 1)用來生成1~5之間的隨機數,用來使程式暫停1~5秒鐘。暫停1秒表示網路狀況好,傳送資料順暢;暫停2~6秒表示網路狀況不好,傳送過程需要1~5秒。)

執行程式:

/usr/local/php/bin/php /opt/zhangyan.php

(/usr/local/php/bin/php因php解析器所在的路徑)

檢視/opt/zhangyan.sh打下的日誌檔案的第一行和最後一行:

可以看出,500程序併發處理這1000條資料只耗費5秒鐘。而按照原來的序列模式,處理每條資料即使只耗費最短的1秒鐘,也需要1000秒,約合16分鐘才能完成。

ps:將php程式作為linux守護程序的方法:

nohup /usr/local/php/bin/php /opt/zhangyan.php 2>&1 > /dev/null &

(nohup命令可以在使用者退出終端後仍然執行程式,「2>&1 > /dev/null」表示不顯示標準輸出和錯誤輸出,最後的&表示推到後台執行。)

PHP多程序併發控制的測試用例

最近遇到乙個問題,linux下的php命令列程式作為守護程序,需要從佇列檔案中讀一行資料,通過tcp協議傳送給外地的接收伺服器,再讀下一行資料,再傳送。當本地與外地的網路狀況不好時,有時候傳送一條資料所耗費的時間就較長,累積起來容易造成佇列堵塞和延遲。於是,我準備用該php命令列程式生成多個子程序,...

PHP多程序併發控制的測試用例

適合於,無需等待處理返回的情況,即可以斷開連線 最近遇到乙個問題,linux下的php命令列程式作為守護程序,需要從佇列檔案中讀一行資料,通過tcp協議傳送給外地的接收伺服器,再讀下一行資料,再傳送。當本地與外地的網路狀況不好時,有時候傳送一條資料所耗費的時間就較長,累積起來容易造成佇列堵塞和延遲。...

PHP的多程序

一般有兩種方法,一種是使用php自帶的pcntl 函式 僅限linux 另一種就是使用popen proc open,然後在php內部控制程序數量。php提供了一系列的pcntl 函式,顧名思義就是process control functions,專門用來管理程序的。最常用的就是pcntl for...