php多进程有什么用,有关php多进程的用法举例
在php中實現多進程,一般有兩種方法,一種是使用PHP自帶的pcntl_*函數(僅限linux),另一種就是使用popen/proc_open,然后在php內部控制進程數量。
使用pcntl_*函數
PHP提供了一系列的pcntl_*函數,顧名思義就是process control functions,專門用來管理進程的。最常用的就是pcntl_fork和pcntl_wait。
pcntl_fork的作用就是從當前的進程再派生出一個子進程。pcntl_wait的作用是掛起當前進程,直到一個子進程中止。
例子:
復制代碼 代碼示例:
//配合pcntl_signal使用
declare(ticks=1);
//最大的子進程數量
$max = 5;
//當前的子進程數量
$child = 0;
//當子進程退出時,會觸發該函數
function sig_handler($sig) {
global $child;
switch($sig) {
case SIGCHLD:
echo 'SIGCHLD received'."\n";
$child--;
}
}
//注冊子進程退出時調用的函數
pcntl_signal(SIGCHLD, "sig_handler");
while(true) {
$child++;
/**
* 這個函數會返回兩個值,一個為0,表示子進程;一個為正整數表示子進程的id
* 所以if和else里的兩段代碼都會執行
* if里的代碼是父進程執行的
* else里的代碼是子進程執行的
*/
$pid = pcntl_fork();
if ($pid) {
//這里是父進程執行的代碼
//如果子進程數超過了最大值,則掛起父進程
//也就是說while語句不會繼續執行
if ($child >= $max) {
pcntl_wait($status);
}
}
else {
//這里是子進程執行的代碼
//如果要執行其他命令的話,使用pcntl_exec
echo "starting new child | now we have $child child process\n";
sleep(rand(3, 5));
exit;
}
}
?>
上面這段代碼就是保證有5個子進程一直在干活,如果$child數量大于$max,就等子進程結束后再繼續運行。子進程結束后會調用 sig_handler函數,sig_handler會將$child
數量減1,那邊while繼續執行。
使用popen/proc_open
popen會創建一個管道來連接該進程,然后使用fread/fgets/stream_get_contents來讀取該進程返回的結果。跟 exec或system之類的函數不同的是,exec會等待命令執行完
成,再運行下面的代碼,但popen不會。proc_open又更加強大一些,支持 stdin和stdout,路徑設置等等。
因為這些函數只負責創建,沒有相應的管理方法,所以只能在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 \"{$input}\" &", "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://www.jbxue.com"; //模擬從隊列文件中讀取到的數據
for ($i = 1; $i <= 1000; $i++)
{
run($input);
echo "Idle process number: " . $p_number . "\n";
}
?>
代碼說明:
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子進程;
建議使用pcntl_*系函數更方便一些,邏輯更清楚。
總結
以上是生活随笔為你收集整理的php多进程有什么用,有关php多进程的用法举例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php判断端口跳转,PHP判断端口是否打
- 下一篇: dede问答模块 那个php文件相对重要