1.1 產生子程序
1.1.1 產生一個子程序
在PHP裡沒有支援多執行緒編程 (multi-threaded programming) ,因此需要寫類似的功能就必須採取多程序編程 (multi-process programming) 的方式。一般在 unix-like 的作業系統下,要寫多程序程式一定會用到fork。在 PHP 裡也不例外。若要在 PHP 中建一個子程序,要叫用 pcntl_fork()函式。
以下是一個簡單的程式樣版:
以下是一個簡單的程式樣版:
樣版
<?php
$pid = pcntl_fork(); //在這裡開始產生程式的分岔
if ($pid == -1) {
die('無法產生子程序');
} else if ($pid) {
// 父程序會進入這裡
} else {
// 子程序會進入這裡
}
?>
子程序的 $pid 會是 0
父程序會拿到子程序的 $pid 編號。
pcntl_fork() 函數目前只能在 Unix-like 的作業系統下使用(精確的說是有 System V API 的作業系統), PHP 目前沒有實作 Windows 環境下的版本。
有關 PHP 裡多程序的其它資料都在 PHP 官方網站上可以找得到。
1.1.2 產生多個子程序
以下這程式會造出多個子程序,子程序造出後父程序會等子程序全都離開後才離開。
範例
<?php
$process_num = 5;
print "老爸:我是老爸,我要生{$process_num}個小孩。\n";
$children = array();
for($i = 1;$i <= $process_num; $i++) {
$pid = pcntl_fork();
if($pid == -1) {
exit(1);
} else if ($pid) {
/*這是老爸專區*/
$children[] = $pid; //紀錄下每個孩子的編號
print "老爸:生了一個第{$i}個孩子,pid是{$pid}\n";
} else {
/*這是小朋友區*/
break; //直接出迴圈
}
}
if($pid) { /* 老爸會在這裡休息 */
$status = null;
/********************************************************
* 下面這行的存在意義是:
* 就算是等所有孩子先行離開以後
* 父程序才開始等子程序
* 父程序仍然會知道子程序已離開
**********************************************************/
sleep(8);
foreach($children as $pid) { //要等每個孩子都離開才離開
pcntl_waitpid($pid, $status);
print "老爸:pid是{$pid}的那個孩子,回去時他告訴我他的狀況是{$status}\n";
}
print '老爸也要走了'."\n";
} else {
/*以下是小朋友遊樂區*/
print "我是第{$i}個小朋友,我要睡{$i}秒\n";
sleep($i);
print "我是第{$i}個小朋友,要走了\n";
exit(0);
}
?>
解說
在此程式用到了 pcntl_waitpid() ,其參數是子程序的 $pid ,程式執行到此函式時,父行程會等到指定的子程序結束以後才繼續動作。
執行結果
老爸:我是老爸,我要生5個小孩。
我是第1個小朋友,我要睡1秒
老爸:生了一個第1個孩子,pid是10487
我是第2個小朋友,我要睡2秒
老爸:生了一個第2個孩子,pid是10488
我是第3個小朋友,我要睡3秒
老爸:生了一個第3個孩子,pid是10489
我是第4個小朋友,我要睡4秒
老爸:生了一個第4個孩子,pid是10490
我是第5個小朋友,我要睡5秒
老爸:生了一個第5個孩子,pid是10491
我是第1個小朋友,要走了
我是第2個小朋友,要走了
我是第3個小朋友,要走了
我是第4個小朋友,要走了
我是第5個小朋友,要走了
老爸:pid是10487的那個孩子,回去時他告訴我他的狀況是0
老爸:pid是10488的那個孩子,回去時他告訴我他的狀況是0
老爸:pid是10489的那個孩子,回去時他告訴我他的狀況是0
老爸:pid是10490的那個孩子,回去時他告訴我他的狀況是0
老爸:pid是10491的那個孩子,回去時他告訴我他的狀況是0
老爸也要走了
文章摘自:http://pkwbim-programming-note.blogspot.tw/2008/01/phpmulti-process-1.html
沒有留言:
張貼留言