最近遇到乙個問題,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**如下:
view plain
print?
<?php
function run($input)
$p_number = $p_number - 1;
$out = popen("/bin/sh /opt/zhangyan.sh \"\" &", "r");
pclose($out);
} function worker_processes($p_number)
} return
$p_number;
} $input = ""; //模擬從佇列檔案中讀取到的資料
for ($i = 1; $i
<= 1000; $i++)
?>
(/opt/zhangyan.php程式用來模擬從佇列檔案中讀取1000行資料,交給子程序/opt/zhangyan.sh去處理。)
/opt/zhangyan.sh**如下:
view plain
print?
#!/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打下的日誌檔案的第一行和最後一行:
head -n 1 /opt/zhangyan.log
2007-11-16 07:54:13
tail -n 1 /opt/zhangyan.log
2007-11-16 07:54:18
可以看出,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多程序併發控制的測試用例
轉http blog.s135.com post 311 最近遇到乙個問題,linux下的php命令列程式作為守護程序,需要從佇列檔案中讀一行資料,通過tcp協議傳送給外地的接收伺服器,再讀下一行資料,再傳送。當本地與外地的網路狀況不好時,有時候傳送一條資料所耗費的時間就較長,累積起來容易造成佇列堵...
PHP多程序併發控制的測試用例
適合於,無需等待處理返回的情況,即可以斷開連線 最近遇到乙個問題,linux下的php命令列程式作為守護程序,需要從佇列檔案中讀一行資料,通過tcp協議傳送給外地的接收伺服器,再讀下一行資料,再傳送。當本地與外地的網路狀況不好時,有時候傳送一條資料所耗費的時間就較長,累積起來容易造成佇列堵塞和延遲。...
PHP的多程序
一般有兩種方法,一種是使用php自帶的pcntl 函式 僅限linux 另一種就是使用popen proc open,然後在php內部控制程序數量。php提供了一系列的pcntl 函式,顧名思義就是process control functions,專門用來管理程序的。最常用的就是pcntl for...