国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > PHP > 正文

PHP多進程編程之僵尸進程問題的理解

2024-05-04 21:50:07
字體:
來源:轉載
供稿:網友

PHP多進程編程之僵尸進程問題的理解

使用pcntl_fork函數可以讓PHP實現多進程并發或者異步處理的效果:http://m.survivalescaperooms.com/php/20180913/11124.html

那么問題是我們產生的進程需要去控制,而不能置之不理。最基本的方式就是fork進程和殺死進程。

通過利用pcntl_fork函數,我們已經有了新的子進程,而子進程接下來完成我們需要處理的內容,那么我們就暫且叫做service()吧,而且我們需要很多個service()進行處理,再次參照我們之前的需求,父進程需要一直循環讀取配置文件,等待文件發生改變。通過對pcntl_fork的方式,很容易我們就可以寫出如下代碼:

  1. $res = config(); 
  2. //kill進程 
  3. for($i = 0; $i < $res[sum]; $i++) { 
  4.   $pid = pcntl_fork(); 
  5.   if ($pid == 0) { 
  6.     service(); 
  7.     return
  8.   } 

代碼中注釋的地方我們需要在配置文件中發生改變的時候殺死進程,殺死進程的的方式很簡單,可以使用kill命令直接殺死,比如(假設pid為123):

1 kill 123

但是我們發現,使用這個殺死進程的方式并沒有真正的把進程殺死,這個子進程被殺死后還占用這個進程的資源,我們成為僵尸進程,僵尸進程是使用kill命令無法殺死的。想要解決這個問題,我們能做的只有兩種方式。

1. shutdown

2. 殺死該進程的父進程。

但是這兩種方法都不行,因為這個程序的目的是監控常駐在服務器內,服務器不能關閉,并且父進程也不能被干掉。這時候我們看到了官方文檔對于fork方法的解釋:

pcntl_wait($status); //等待子進程中斷,防止子進程成為僵尸進程。

原來有種方式可以防止進程成為僵尸進程,但是,官網給出的代碼是這樣子的:

  1. $pid = pcntl_fork(); 
  2. //父進程和子進程都會執行下面代碼 
  3. if ($pid == -1) { 
  4.   //錯誤處理:創建子進程失敗時返回-1. 
  5.    die('could not fork'); 
  6. else if ($pid) { 
  7.    //父進程會得到子進程號,所以這里是父進程執行的邏輯 
  8.    pcntl_wait($status); //等待子進程中斷,防止子進程成為僵尸進程。 
  9. else { 
  10.    //子進程得到的$pid為0, 所以這里是子進程執行的邏輯。 

什么意思呢?就是父進程會等待子進程運行,等子進程運行結束之后,才會進行下一步,并且也會消除僵尸進程。但是這里又和我們的需求不符合了,我們的子進程為一個死循環的程序,不斷的查找輸出,更本沒有結束的時候,并且我們需要的是異步處理而不是同步。但是這個方法可以用嗎?其實當然可以。

在pcntl_wait的文檔中是這么解釋這個函數的:

wait函數刮起當前進程的執行直到一個子進程退出或接收到一個信號要求中斷當前進程或調用一個信號處理函數。 如果一個子進程在調用此函數時已經退出(俗稱僵尸進程),此函數立刻返回。子進程使用的所有系統資源將 被釋放。關于wait在您系統上工作的詳細規范請查看您系統的wait(2)手冊。

我們發現,當這個函數發現子進程成為了僵尸進程就會釋放僵尸進程的資源——前提是這個僵尸進程為這個父進程的子進程。那么我們就可以巧妙的利用這個方式讓這些僵尸進程釋放資源了,所以就有了如下代碼:

posix_kill(123, 9);

pcntl_wait($status);

這樣我們先使用kill干掉這個進程,這個進程就不會再運行了,但是這個進程成為了僵尸進程,占用著資源,我們下一句就執行一次pcntl_wait()讓這些僵尸進程釋放資源,這樣,子進程才真正的被終止了,僵尸進程被消除了。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 洪江市| 永靖县| 子洲县| 磐石市| 光山县| 寻乌县| 怀集县| 乌审旗| 巧家县| 呼伦贝尔市| 裕民县| 贵溪市| 鄱阳县| 铅山县| 泽州县| 昌图县| 马鞍山市| 汝州市| 闽侯县| 澎湖县| 太白县| 泸州市| 鄂尔多斯市| 波密县| 扶沟县| 华池县| 孟州市| 英超| 武穴市| 永兴县| 庄浪县| 江阴市| 辉县市| 娄底市| 磴口县| 鸡西市| 攀枝花市| 剑河县| 桐城市| 永州市| 上思县|