首頁 >後端開發 >php教程 >解析PHP多進程編程

解析PHP多進程編程

藏色散人
藏色散人轉載
2021-04-15 09:12:182815瀏覽

推薦:《PHP影片教學

#PHP多進程程式設計

使用多進程的優點:

    1. 使用多进程, 子进程结束以后, 内核会负责回收资源
    2. 使用多进程,子进程异常退出不会导致整个进程Thread退出. 父进程还有机会重建流程.
    3. 一个常驻主进程, 只负责任务分发, 逻辑更清楚.

PHP中實現多進程,Let's Go.

我們需要安裝pcnt擴充功能

pcntl是process control的縮寫,通常,php會預設安裝這個擴充。使用phpinfo()函數查看擴充功能是否存在。

解析PHP多進程編程

使用pcntl_fork() 函數建立子進程

pcntl_fork作用就是建立和目前進程一樣的子進程,這個子進程程式碼段和目前進程一模一樣,但是擁有自己的資料段。看一個最簡單的創建子程序的方法:

<?php /**
 *  hedong
 * @date 2017-04-03
 */

$parentPid = getmypid(); // 获取父进程id $childPid = pcntl_fork(); // 创建子进程 switch($childPid) {
    case -1:
        print "创建子进程失败!".PHP_EOL;
        exit;
    case 0:
        print "我是子进程,进程ID:{$childPid}".PHP_EOL;
        break;
    default:
        print "我是父进程,进程ID:{$parentPid},子进程ID: {$childPid}".PHP_EOL;
}
?>
pcntl_fork()调用成功以后,一个程序变成了两个程序:一个程序得到的$pid变量值是0,它是子进程;另一个程序得到的$pid的值大于0,这个值是子进程的PID,它是父进程。

輸出結果:

解析PHP多進程編程

子程序回收

#① 阻塞方式
剛剛有ps麼?一般我習慣用ps aux加上grep指令來找出運行著的後台進程。其中有一列STAT,標識了每個行程的運作狀態。這裡,我們關注狀態Z:殭屍(Zombie)。當子行程比父行程先退出,而父行程沒對其做任何處理的時候,子行程將會變成殭屍行程。殭屍行程雖然不佔什麼內存,但是很礙眼。 (別忘了它們還佔用PID)

一般來說,在父行程結束之前回收掛掉的子行程就可以了。在pcntl擴充裡面有一個pcntl_wait()函數,透過這個方法等待進程結束,然後回收已經結束的進程。

<?php /**
 *  hedong
 * @date 2017-04-03
 */

$parentPid = getmypid(); // 获取父进程id $childPid = pcntl_fork(); // 创建子进程 switch($childPid) {
    case -1:
        print "创建子进程失败!".PHP_EOL;
        exit;
    case 0:
        print "我是子进程,进程ID:{$childPid}".PHP_EOL;
        break;
    default:
        pcntl_wait($status); // 子进程执行完后才执行父进程         print "我是父进程,进程ID:{$parentPid},子进程ID: {$childPid}".PHP_EOL;
}

② 非阻塞方式
阻塞方式失去了多進程的平行性。還有一種方法,既可以回收已經結束的子進程,又可以並行。這就是非阻塞的方式。

<?php /**
 *  hedong
 * @date 2017-04-03
 */

for ($i = 1; $i <= 5; ++$i) {
    $pid = pcntl_fork(); // 创建子进程

    if (!$pid) {
        sleep(1);
        print "In child $i\n";
        exit($i);
    }
}

// pcntl_waitpid 第一个参数为 0 代表处理全部子进程

while (pcntl_waitpid(0, $status) != -1) {
    $status = pcntl_wexitstatus($status);
    echo "Child $status completed\n";
}

如果父行程先掛了怎麼辦?

會發生什麼事?什麼事也不會發生,子進程依舊還在運作。但這個時候,子進程會被交給1號進程,1號進程成為了這些子進程的繼父。 1號進程會很好地處理這些進程的資源,當它們結束時1號進程會自動回收資源。所以,另一個處理殭屍行程的臨時辦法是關閉它們的父行程。

最後要注意的:

進程控制不能被應用在Web伺服器環境,當其被用於Web服務環境時可能會帶來意外的結果。 -- 摘自PHP手冊

參考:

http://www.hackingwithphp.com/16/1/3/getting-into-multiprocessing

http://www.jb51.net/article/71232.htm

http://www.laruence.com/2009/06/11/930.html

http://imhuchao.com/596.html

https://www.pureweber.com/article/php-multi-process-programming-preview/
#

以上是解析PHP多進程編程的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除