標籤:++ 一個 efi 技術分享 注意 進入 waitpid fine fork
php中進程的阻塞,主要是父進程等待子進程退出。
1.php代碼如下:
<?php//定義進程數量define(‘FORK_NUMS‘, 5);//用於儲存進程pid$pids = array();//我們建立5個子進程for ($i = 0; $i < FORK_NUMS; ++$i) { $pids[$i] = pcntl_fork(); if ($pids[$i] == -1) { die(‘fork error‘); } else if ($pids[$i]) { //這裡是父進程空間,也就是主進程 //我們的for迴圈第一次進入到這裡時,pcntl_wait會掛起當前主進程,等待第一個子進程執行完畢退出 //注意for迴圈的代碼是在主進程的,掛起主進程,相當於當前的for迴圈也阻塞在這裡了 //第一個子進程退出後,然後再建立第二個子進程,到這裡後又掛起,等待第二個子進程退出,繼續建立第三個,等等。。 pcntl_wait($status); } else { //這裡是子進程空間 echo "父進程ID: ", posix_getppid(), " 進程ID : ", posix_getpid(), " {$i} \r\n"; //我們讓子進程等待3秒,再退出 sleep(3); exit; }}
上面代碼結果如下:
如果我們把pcntl_wait拿到for迴圈外,會是個什麼結果?
2.php代碼如下:
<?php//定義進程數量define(‘FORK_NUMS‘, 5);//用於儲存進程pid$pids = array();//我們建立5個子進程for ($i = 0; $i < FORK_NUMS; ++$i) { $pids[$i] = pcntl_fork(); if ($pids[$i] == -1) { die(‘fork error‘); } else if ($pids[$i]) { } else { //這裡是子進程空間 echo "父進程ID: ", posix_getppid(), " 進程ID : ", posix_getpid(), " {$i} \r\n"; //我們讓子進程等待3秒,再退出 sleep(3); exit; }}//我們把pcntl_waitpid放到for迴圈外面,那樣在for迴圈裡建立子進程就不會阻塞了//但是在這裡仍會阻塞,主進程要等待5個子進程都退出後,才退出。foreach ($pids as $pid) { pcntl_waitpid($pid, $status);}
上面代碼結果如下:
pcntl_wait的第二個參數可以用來設定主進程不等待子進程退出,繼續執行後續代碼。
3.php代碼如下:
<?php//定義進程數量define(‘FORK_NUMS‘, 5);//用於儲存進程pid$pids = array();//我們建立5個子進程for ($i = 0; $i < FORK_NUMS; ++$i) { $pids[$i] = pcntl_fork(); if ($pids[$i] == -1) { die(‘fork error‘); } else if ($pids[$i]) { //這裡是父進程空間,也就是主進程 //這裡與1.php的代碼只有一點不同,就是加了第二個參數WNOHANG //for迴圈到這裡時,就不會掛起主進程,而是繼續執行後續代碼 pcntl_wait($status, WNOHANG); } else { //這裡是子進程空間 echo "父進程ID: ", posix_getppid(), " 進程ID : ", posix_getpid(), " {$i} \r\n"; //我們讓子進程等待3秒,再退出 sleep(3); exit; }}//在這裡我們等待10秒,不然子進程還沒執行完,主進程就退出了,看不出效果sleep(10);
上面代碼結果如下:
代碼3.php與2.php效果一樣,pcntl_wait()函數的作用只是用來讓父進程等待子進程退出,預設情況下會阻塞主進程。
php 多進程 父進程的阻塞與非阻塞