您好,登錄后才能下訂單哦!
這篇文章主要介紹了如何解析PHP多進(jìn)程編程,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
PHP多進(jìn)程編程
使用多進(jìn)程的優(yōu)點(diǎn):
1. 使用多進(jìn)程, 子進(jìn)程結(jié)束以后, 內(nèi)核會(huì)負(fù)責(zé)回收資源 2. 使用多進(jìn)程,子進(jìn)程異常退出不會(huì)導(dǎo)致整個(gè)進(jìn)程Thread退出. 父進(jìn)程還有機(jī)會(huì)重建流程. 3. 一個(gè)常駐主進(jìn)程, 只負(fù)責(zé)任務(wù)分發(fā), 邏輯更清楚.
PHP中實(shí)現(xiàn)多進(jìn)程,Let's Go.
我們需要安裝pcnt擴(kuò)展
pcntl是process control的縮寫(xiě),通常,php會(huì)默認(rèn)安裝這個(gè)擴(kuò)展。使用phpinfo()函數(shù)查看擴(kuò)展是否存在。
使用pcntl_fork() 函數(shù)創(chuàng)建子進(jìn)程
pcntl_fork作用就是創(chuàng)建和當(dāng)前進(jìn)程一樣的子進(jìn)程,這個(gè)子進(jìn)程代碼段和當(dāng)前進(jìn)程一模一樣,但是擁有自己的數(shù)據(jù)段??匆粋€(gè)最簡(jiǎn)單的創(chuàng)建子進(jìn)程的方法:
<?php /** * hedong * @date 2017-04-03 */ $parentPid = getmypid(); // 獲取父進(jìn)程id $childPid = pcntl_fork(); // 創(chuàng)建子進(jìn)程 switch($childPid) { case -1: print "創(chuàng)建子進(jìn)程失敗!".PHP_EOL; exit; case 0: print "我是子進(jìn)程,進(jìn)程ID:{$childPid}".PHP_EOL; break; default: print "我是父進(jìn)程,進(jìn)程ID:{$parentPid},子進(jìn)程ID: {$childPid}".PHP_EOL; } ?>
pcntl_fork()調(diào)用成功以后,一個(gè)程序變成了兩個(gè)程序:一個(gè)程序得到的$pid變量值是0,它是子進(jìn)程;另一個(gè)程序得到的$pid的值大于0,這個(gè)值是子進(jìn)程的PID,它是父進(jìn)程。
輸出結(jié)果:
子進(jìn)程回收
① 阻塞方式
剛剛有ps么?一般我習(xí)慣用ps aux加上grep命令來(lái)查找運(yùn)行著的后臺(tái)進(jìn)程。其中有一列STAT,標(biāo)識(shí)了每個(gè)進(jìn)程的運(yùn)行狀態(tài)。這里,我們關(guān)注狀態(tài)Z:僵尸(Zombie)。當(dāng)子進(jìn)程比父進(jìn)程先退出,而父進(jìn)程沒(méi)對(duì)其做任何處理的時(shí)候,子進(jìn)程將會(huì)變成僵尸進(jìn)程。僵尸進(jìn)程雖然不占什么內(nèi)存,但是很礙眼。(別忘了它們還占用著PID)
一般來(lái)說(shuō),在父進(jìn)程結(jié)束之前回收掛掉的子進(jìn)程就可以了。在pcntl擴(kuò)展里面有一個(gè)pcntl_wait()函數(shù),通過(guò)這個(gè)方法等待進(jìn)程結(jié)束,然后回收已經(jīng)結(jié)束的進(jìn)程。
<?php /** * hedong * @date 2017-04-03 */ $parentPid = getmypid(); // 獲取父進(jìn)程id $childPid = pcntl_fork(); // 創(chuàng)建子進(jìn)程 switch($childPid) { case -1: print "創(chuàng)建子進(jìn)程失敗!".PHP_EOL; exit; case 0: print "我是子進(jìn)程,進(jìn)程ID:{$childPid}".PHP_EOL; break; default: pcntl_wait($status); // 子進(jìn)程執(zhí)行完后才執(zhí)行父進(jìn)程 print "我是父進(jìn)程,進(jìn)程ID:{$parentPid},子進(jìn)程ID: {$childPid}".PHP_EOL; }
② 非阻塞方式
阻塞方式失去了多進(jìn)程的并行性。還有一種方法,既可以回收已經(jīng)結(jié)束的子進(jìn)程,又可以并行。這就是非阻塞的方式。
<?php /** * hedong * @date 2017-04-03 */ for ($i = 1; $i <= 5; ++$i) { $pid = pcntl_fork(); // 創(chuàng)建子進(jìn)程 if (!$pid) { sleep(1); print "In child $i\n"; exit($i); } } // pcntl_waitpid 第一個(gè)參數(shù)為 0 代表處理全部子進(jìn)程 while (pcntl_waitpid(0, $status) != -1) { $status = pcntl_wexitstatus($status); echo "Child $status completed\n"; }
如果父進(jìn)程先掛了怎么辦?
會(huì)發(fā)生什么?什么也不會(huì)發(fā)生,子進(jìn)程依舊還在運(yùn)行。但是這個(gè)時(shí)候,子進(jìn)程會(huì)被交給1號(hào)進(jìn)程,1號(hào)進(jìn)程成為了這些子進(jìn)程的繼父。1號(hào)進(jìn)程會(huì)很好地處理這些進(jìn)程的資源,當(dāng)它們結(jié)束時(shí)1號(hào)進(jìn)程會(huì)自動(dòng)回收資源。所以,另一種處理僵尸進(jìn)程的臨時(shí)辦法是關(guān)閉它們的父進(jìn)程。
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“如何解析PHP多進(jìn)程編程”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。