linux下php多進程編程

    php在很多情況用在web開發中,通常情況下一次請求對應一個php進程,進程執行完返回數據銷燬執行過程中的中間變量代碼,在一些perfork類型的的sapi中,它又會等待下一個請求過來重新初始化執行環境、執行腳本,已經執行完成後的清理工作。但在如命令行下有時候一個進程滿足不了需求,比如微博的異步發送,如果是用php腳本處理的話,腳本需要從發送隊列中取數據,然後對數據進行處理,一個進程顯然太慢,解決這種問題可以用php自帶的popen、exect之類的函數,也可以用php多進程編程來解決。

  

  php的多進程管理需要pcntlposix擴展,在官方手冊中:

POSIX functions are enabled by default. You can disable POSIX-like functions with --disable-posix 。

Process Control support in PHP is not enabled by default. You have to compile the CGI or CLI version of PHP with --enable-pcntl configuration option when compiling PHP to enable Process Control support.

因爲posix協議是針對unix系的,window下就不考慮了。下面用這兩個擴展中的函數寫一個多進程的daemon進程。

<?php
$max 	 = 6;
$current = 0;
pcntl_signal(SIGCHLD, "reduce_current");

/*
 * signal callback function 
*/
function reduce_current($signal)
{
	global $current;
	if ($signal === SIGCHLD) {
		$current--;
	}
}

// become a daemon
if (($pid = pcntl_fork()) === -1) {
	die("fork error");
} elseif ($pid) {
	exit;
} else {
	if (posix_setsid() === -1)
		die("setsid error");

	if (($pid = pcntl_fork()) === -1) 
		die("fork error");
	elseif($pid) 
		exit;

}

while(1) {
	$current++;
	if (($pid = pcntl_fork()) === -1) {
		//log and  exit

	} elseif ($pid) {
		//father process
		if ($current >= $max ) {
			//blocking
			if(pcntl_wait($status) === -1) {
				//log or exit
			}
		}

	} else {
		//child process 
		//do something repalce sleep
		sleep(3);
		exit;
	}
}

   代碼中規定腳本最大可以fork出6個進程,但數據達到6個後,會調用pcntl_warit使父進程掛起。當子進程執行完自己的任務(此處以sleep 3 秒代替)後退出時,父進程通過 捕獲子進程退出狀態,通過pcntl_signal 註冊的的回調函數使其子進程數量減1,然後又可以繼續fork子進程。如圖中,父進程通過兩次fork變成一個daemon進程,其父進程id爲1(即init進程),其6個子進程的ppid與它的pid一樣,都是918。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章