婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > 什么是PHP7中的孤兒進程與僵尸進程

什么是PHP7中的孤兒進程與僵尸進程

熱門標簽:抖音有個地圖標注是什么意思 地下城堡2圖九地圖標注 海南人工外呼系統有效果嗎 保定crm外呼系統運營商 阿里云400電話申請加工單 西區企業怎么做地圖標注入駐 七魚外呼系統停用嗎 九江外呼系統 智能電話機器人排名前十名南京

基本概念

我們知道在unix/linux中,正常情況下,子進程是通過父進程創建的,子進程在創建新的進程。子進程的結束和父進程的運行是一個異步過程,即父進程永遠無法預測子進程 到底什么時候結束。 當一個 進程完成它的工作終止之后,它的父進程需要調用wait()或者waitpid()系統調用取得子進程的終止狀態。

孤兒進程

一個父進程退出,而它的一個或多個子進程還在運行,那么那些子進程將成為孤兒進程。孤兒進程將被init進程(進程號為1)所收養,并由init進程對它們完成狀態收集工作。

僵尸進程

一個進程使用fork創建子進程,如果子進程退出,而父進程并沒有調用wait或waitpid獲取子進程的狀態信息,那么子進程的進程描述符仍然保存在系統中。這種進程稱之為僵死進程。

問題及危害

unix提供了一種機制可以保證只要父進程想知道子進程結束時的狀態信息, 就可以得到。這種機制就是: 在每個進程退出的時候,內核釋放該進程所有的資源,包括打開的文件,占用的內存等。 但是仍然為其保留一定的信息(包括進程號the process ID,退出狀態the termination status of the process,運行時間the amount of CPU time taken by the process等)。直到父進程通過wait / waitpid來取時才釋放。 但這樣就導致了問題,如果進程不調用wait / waitpid的話, 那么保留的那段信息就不會釋放,其進程號就會一直被占用,但是系統所能使用的進程號是有限的,如果大量的產生僵死進程,將因為沒有可用的進程號而導致系統不能產生新的進程. 此即為僵尸進程的危害,應當避免。

孤兒進程是沒有父進程的進程,孤兒進程這個重任就落到了init進程身上,init進程就好像是一個民政局,專門負責處理孤兒進程的善后工作。每當出現一個孤兒進程的時候,內核就把孤 兒進程的父進程設置為init,而init進程會循環地wait()它的已經退出的子進程。這樣,當一個孤兒進程凄涼地結束了其生命周期的時候,init進程就會代表黨和政府出面處理它的一切善后工作。因此孤兒進程并不會有什么危害。

任何一個子進程(init除外)在exit()之后,并非馬上就消失掉,而是留下一個稱為僵尸進程(Zombie)的數據結構,等待父進程處理。這是每個 子進程在結束時都要經過的階段。如果子進程在exit()之后,父進程沒有來得及處理,這時用ps命令就能看到子進程的狀態是“Z”。如果父進程能及時 處理,可能用ps命令就來不及看到子進程的僵尸狀態,但這并不等于子進程不經過僵尸狀態。 如果父進程在子進程結束之前退出,則子進程將由init接管。init將會以父進程的身份對僵尸狀態的子進程進行處理。

僵尸進程危害場景

例如有個進程,它定期的產 生一個子進程,這個子進程需要做的事情很少,做完它該做的事情之后就退出了,因此這個子進程的生命周期很短,但是,父進程只管生成新的子進程,至于子進程 退出之后的事情,則一概不聞不問,這樣,系統運行上一段時間之后,系統中就會存在很多的僵死進程,倘若用ps命令查看的話,就會看到很多狀態為Z的進程。 嚴格地來說,僵死進程并不是問題的根源,罪魁禍首是產生出大量僵死進程的那個父進程。因此,當我們尋求如何消滅系統中大量的僵死進程時,答案就是把產生大 量僵死進程的那個元兇槍斃掉(也就是通過kill發送SIGTERM或者SIGKILL信號啦)。槍斃了元兇進程之后,它產生的僵死進程就變成了孤兒進 程,這些孤兒進程會被init進程接管,init進程會wait()這些孤兒進程,釋放它們占用的系統進程表中的資源,這樣,這些已經僵死的孤兒進程 就能瞑目而去了。

孤兒進程和僵尸進程測試

1、孤兒進程被init進程收養

$pid = pcntl_fork();

if ($pid > 0) {

  // 顯示父進程的進程ID,這個函數可以是getmypid(),也可以用posix_getpid()

  echo "Father PID:" . getmypid() . PHP_EOL;

  // 讓父進程停止兩秒鐘,在這兩秒內,子進程的父進程ID還是這個父進程

  sleep(2);

} else if (0 == $pid) {

  // 讓子進程循環10次,每次睡眠1s,然后每秒鐘獲取一次子進程的父進程進程ID

  for ($i = 1; $i = 10; $i++) {

    sleep(1);

    // posix_getppid()函數的作用就是獲取當前進程的父進程進程ID

    echo posix_getppid() . PHP_EOL;

  }

} else {

  echo "fork error." . PHP_EOL;

}

測試結果:

php daemo001.php

Father PID:18046

18046

18046

www@iZ2zec3dge6rwz2uw4tveuZ:~/test$ 1

1

1

1

1

1

1

1

2、僵尸進程和危害 

執行以下代碼 php zombie1.php

$pid = pcntl_fork();

if( $pid > 0 ){

  // 下面這個函數可以更改php進程的名稱

  cli_set_process_title('php father process');

  // 讓主進程休息60秒鐘

  sleep(60);

} else if( 0 == $pid ) {

  cli_set_process_title('php child process');

  // 讓子進程休息10秒鐘,但是進程結束后,父進程不對子進程做任何處理工作,這樣這個子進程就會變成僵尸進程

  sleep(10);

} else {

  exit('fork error.'.PHP_EOL);

}

執行結果,另外一個終端窗口

www@iZ2zec3dge6rwz2uw4tveuZ:~$ ps -aux|grep -v "grep\|nginx\|php-fpm" | grep php

www   18458 0.5 1.2 204068 25920 pts/1  S+  16:34  0:00 php father process

www   18459 0.0 0.3 204068 6656 pts/1  S+  16:34  0:00 php child process

www@iZ2zec3dge6rwz2uw4tveuZ:~$ ps -aux|grep -v "grep\|nginx\|php-fpm" | grep php

www   18458 0.0 1.2 204068 25920 pts/1  S+  16:34  0:00 php father process

www   18459 0.0 0.0   0   0 pts/1  Z+  16:34  0:00 [php] defunct>

通過執行 ps -aux 命令可以看到,當程序在前十秒內運行的時候,php child process 的狀態列為 [S+],然而在十秒鐘過后,這個狀態變成了 [Z+],也就是變成了危害系統的僵尸進程。

那么,問題來了?如何避免僵尸進程呢?

PHP通過 pcntl_wait() 和 pcntl_waitpid() 兩個函數來幫我們解決這個問題。了解Linux系統編程的應該知道,看名字就知道這其實就是PHP把C語言中的 wait() 和 waitpid() 包裝了一下。

通過代碼演示 pcntl_wait() 來避免僵尸進程。

pcntl_wait() 函數:

這個函數的作用就是 “ 等待或者返回子進程的狀態 ”,當父進程執行了該函數后,就會阻塞掛起等待子進程的狀態一直等到子進程已經由于某種原因退出或者終止。

換句話說就是如果子進程還沒結束,那么父進程就會一直等等等,如果子進程已經結束,那么父進程就會立刻得到子進程狀態。這個函數返回退出的子進程的進程 ID 或者失敗返回 -1。

執行以下代碼 zombie2.php

$pid = pcntl_fork();

if ($pid > 0) {

  // 下面這個函數可以更改php進程的名稱

  cli_set_process_title('php father process');

  // 返回$wait_result,就是子進程的進程號,如果子進程已經是僵尸進程則為0

  // 子進程狀態則保存在了$status參數中,可以通過pcntl_wexitstatus()等一系列函數來查看$status的狀態信息是什么

  $wait_result = pcntl_wait($status);

  print_r($wait_result);

  print_r($status);

  // 讓主進程休息60秒鐘

  sleep(60);

} else if (0 == $pid) {

  cli_set_process_title('php child process');

  // 讓子進程休息10秒鐘,但是進程結束后,父進程不對子進程做任何處理工作,這樣這個子進程就會變成僵尸進程

  sleep(10);

} else {

  exit('fork error.' . PHP_EOL);

}

在另外一個終端中通過ps -aux查看,可以看到在前十秒內,php child process 是 [S+] 狀態,然后十秒鐘過后進程消失了,也就是被父進程回收了,沒有變成僵尸進程。

www@iZ2zec3dge6rwz2uw4tveuZ:~/test$ ps -aux|grep -v "grep\|nginx\|php-fpm" | grep php

www@iZ2zec3dge6rwz2uw4tveuZ:~/test$ ps -aux|grep -v "grep\|nginx\|php-fpm" | grep php

www   18519 0.5 1.2 204068 25576 pts/1  S+  16:42  0:00 php father process

www   18520 0.0 0.3 204068 6652 pts/1  S+  16:42  0:00 php child process

www@iZ2zec3dge6rwz2uw4tveuZ:~/test$ ps -aux|grep -v "grep\|nginx\|php-fpm" | grep php

www   18519 0.0 1.2 204068 25576 pts/1  S+  16:42  0:00 php father process

但是,pcntl_wait() 有個很大的問題,就是阻塞。父進程只能掛起等待子進程結束或終止,在此期間父進程什么都不能做,這并不符合多快好省原則,所以 pcntl_waitpid() 閃亮登場。pcntl_waitpid( pid, status, $option = 0 )的第三個參數如果設置為WNOHANG,那么父進程不會阻塞一直等待到有子進程退出或終止,否則將會和pcntl_wait()的表現類似。

修改第三個案例的代碼,但是,我們并不添加WNOHANG,演示說明pcntl_waitpid()功能:

$pid = pcntl_fork();

if ($pid > 0) {

  // 下面這個函數可以更改php進程的名稱

  cli_set_process_title('php father process');

  // 返回值保存在$wait_result中

  // $pid參數表示 子進程的進程ID

  // 子進程狀態則保存在了參數$status中

  // 將第三個option參數設置為常量WNOHANG,則可以避免主進程阻塞掛起,此處父進程將立即返回繼續往下執行剩下的代碼

  $wait_result = pcntl_waitpid($pid, $status);

  var_dump($wait_result);

  var_dump($status);

  // 讓主進程休息60秒鐘

  sleep(60);

} else if (0 == $pid) {

  cli_set_process_title('php child process');

  // 讓子進程休息10秒鐘,但是進程結束后,父進程不對子進程做任何處理工作,這樣這個子進程就會變成僵尸進程

  sleep(10);

} else {

  exit('fork error.' . PHP_EOL);

}

下面是運行結果,一個執行php zombie3.php 程序的終端窗口

www@iZ2zec3dge6rwz2uw4tveuZ:~/test$ php zombie3.php

int(18586)

int(0)

^C  

ctrl-c 發送 SIGINT 信號給前臺進程組中的所有進程。常用于終止正在運行的程序。

下面是ps -aux終端窗口

www@iZ2zec3dge6rwz2uw4tveuZ:~$ ps -aux|grep -v "grep\|nginx\|php-fpm" | grep php

www   18605 0.3 1.2 204068 25756 pts/1  S+  16:52  0:00 php father process

www   18606 0.0 0.3 204068 6636 pts/1  S+  16:52  0:00 php child process

www@iZ2zec3dge6rwz2uw4tveuZ:~$ ps -aux|grep -v "grep\|nginx\|php-fpm" | grep php

www   18605 0.1 1.2 204068 25756 pts/1  S+  16:52  0:00 php father process

www@iZ2zec3dge6rwz2uw4tveuZ:~$ ps -aux|grep -v "grep\|nginx\|php-fpm" | grep php

www   18605 0.0 1.2 204068 25756 pts/1  S+  16:52  0:00 php father process

www@iZ2zec3dge6rwz2uw4tveuZ:~$ ps -aux|grep -v "grep\|nginx\|php-fpm" | grep php // ctrl-c 后不再被阻塞

www@iZ2zec3dge6rwz2uw4tveuZ:~$

實際上可以看到主進程是被阻塞的,一直到第十秒子進程退出了,父進程不再阻塞  

修改第四段代碼,添加第三個參數WNOHANG,代碼如下:

$pid = pcntl_fork();

if ($pid > 0) {

  // 下面這個函數可以更改php進程的名稱

  cli_set_process_title('php father process');

  // 返回值保存在$wait_result中

  // $pid參數表示 子進程的進程ID

  // 子進程狀態則保存在了參數$status中

  // 將第三個option參數設置為常量WNOHANG,則可以避免主進程阻塞掛起,此處父進程將立即返回繼續往下執行剩下的代碼

  $wait_result = pcntl_waitpid($pid, $status, WNOHANG);

  var_dump($wait_result);

  var_dump($status);

  echo "不阻塞,運行到這里" . PHP_EOL;

  // 讓主進程休息60秒鐘

  sleep(60);

} else if (0 == $pid) {

  cli_set_process_title('php child process');

  // 讓子進程休息10秒鐘,但是進程結束后,父進程不對子進程做任何處理工作,這樣這個子進程就會變成僵尸進程

  sleep(10);

} else {

  exit('fork error.' . PHP_EOL);

}

執行 php zombie4.php

www@iZ2zec3dge6rwz2uw4tveuZ:~/test$ php zombie4.php

int(0)

int(0)

不阻塞,運行到這里 

另一個ps -aux終端窗口

www@iZ2zec3dge6rwz2uw4tveuZ:~$ ps -aux|grep -v "grep\|nginx\|php-fpm" | grep php

www   18672 0.3 1.2 204068 26284 pts/1  S+  17:00  0:00 php father process

www   18673 0.0 0.3 204068 6656 pts/1  S+  17:00  0:00 php child process

www@iZ2zec3dge6rwz2uw4tveuZ:~$ ps -aux|grep -v "grep\|nginx\|php-fpm" | grep php

www   18672 0.0 1.2 204068 26284 pts/1  S+  17:00  0:00 php father process

www   18673 0.0 0.0   0   0 pts/1  Z+  17:00  0:00 [php] defunct>

實際上可以看到主進程是被阻塞的,一直到第十秒子進程退出了,父進程不再阻塞?! ?/p>

問題出現了,竟然php child process進程狀態竟然變成了[Z+],這是怎么搞得?回頭分析一下代碼:
我們看到子進程是睡眠了十秒鐘,而父進程在執行pcntl_waitpid()之前沒有任何睡眠且本身不再阻塞,所以,主進程自己先執行下去了,而子進程在足足十秒鐘后才結束,進程狀態自然無法得到回收。

如果我們將代碼修改一下,就是在主進程的pcntl_waitpid()前睡眠15秒鐘,這樣就可以回收子進程了。但是即便這樣修改,細心想的話還是會有個問題,那就是在子進程結束后,在父進程執行pcntl_waitpid()回收前,有五秒鐘的時間差,在這個時間差內,php child process也將會是僵尸進程。那么,pcntl_waitpid()如何正確使用?。窟@樣用,看起來畢竟不太科學。

那么,是時候引入信號學了!

您可能感興趣的文章:
  • PHP多進程編程之僵尸進程問題的理解
  • php 的多進程操作實踐案例分析
  • php 多進程編程父進程的阻塞與非阻塞實例分析
  • php實現的簡單多進程服務器類完整示例
  • 深入解析PHP中的(偽)多線程與多進程
  • 深入探究PHP的多進程編程方法
  • PHP使用pcntl_fork實現多進程下載圖片的方法
  • PHP 多進程 解決難題
  • 解析PHP實現多進程并行執行腳本
  • 以實例全面講解PHP中多進程編程的相關函數的使用
  • PHP基于文件鎖解決多進程同時讀寫一個文件問題示例
  • php多進程并發編程防止出現僵尸進程的方法分析

標簽:涼山 九江 甘肅 遼陽 梅河口 十堰 韶關 昭通

巨人網絡通訊聲明:本文標題《什么是PHP7中的孤兒進程與僵尸進程》,本文關鍵詞  什么,是,PHP7,中的,孤兒,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《什么是PHP7中的孤兒進程與僵尸進程》相關的同類信息!
  • 本頁收集關于什么是PHP7中的孤兒進程與僵尸進程的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    国产一区二区视频在线| 美女国产一区二区三区| 久久在线观看免费| 在线精品亚洲一区二区不卡| 国产性天天综合网| 日本韩国精品在线| 91片在线免费观看| 婷婷成人综合网| 久久爱www久久做| 国产综合成人久久大片91| 精品一区二区三区日韩| 国产一区二区三区观看| 久久91精品久久久久久秒播| 精品一区二区三区久久久| 国产精品一二三| 欧美一区二视频| 91麻豆123| 国产校园另类小说区| 亚洲电影视频在线| 日韩精品免费视频人成| 成人免费视频app| 日韩精品一区二区三区在线观看| 国产亚洲欧美一区在线观看| 国产欧美日韩在线看| 久久久久久久久久电影| 亚洲视频精选在线| 国产精品亚洲一区二区三区妖精| 国产乱对白刺激视频不卡| 欧美三日本三级三级在线播放| 在线播放视频一区| 一区二区不卡在线播放 | 日韩一级黄色片| 美女视频黄免费的久久 | 日韩av不卡在线观看| 日韩欧美的一区二区| 另类小说视频一区二区| 久久久久高清精品| 蜜臀av性久久久久av蜜臀妖精| 久久午夜免费电影| 91丨porny丨户外露出| 亚洲成人免费视频| 日韩欧美国产系列| 国产精品1区2区3区在线观看| 亚洲日本在线a| 丁香天五香天堂综合| 香蕉影视欧美成人| 国产精品成人午夜| 日韩精品一区二区三区三区免费| 国产精一品亚洲二区在线视频| 亚洲资源中文字幕| 国产人妖乱国产精品人妖| 欧美色男人天堂| 国产白丝精品91爽爽久久| 亚洲永久精品大片| 日韩欧美亚洲国产另类| 成人美女视频在线观看| 美女视频一区二区三区| 一区二区三区精品在线观看| 欧美激情在线一区二区三区| 91精品欧美综合在线观看最新| 亚洲成va人在线观看| 中文字幕中文字幕一区| 日韩免费视频一区| 懂色一区二区三区免费观看| 亚洲一区视频在线观看视频| 亚洲欧美色一区| 中文字幕va一区二区三区| 欧美性受极品xxxx喷水| 欧美特级限制片免费在线观看| 成人精品小蝌蚪| 97se亚洲国产综合自在线| 国产做a爰片久久毛片| 亚洲mv在线观看| 午夜精品久久久久久久蜜桃app| 国产精品久久777777| 国产精品少妇自拍| 亚洲欧美电影院| 2017欧美狠狠色| 国产精品麻豆久久久| 亚洲视频狠狠干| 亚洲女子a中天字幕| 夜夜亚洲天天久久| 亚洲欧洲综合另类在线| 一区二区欧美精品| 婷婷久久综合九色综合绿巨人| 亚洲综合偷拍欧美一区色| 中文字幕一区二区日韩精品绯色| 精品日韩成人av| 国产欧美久久久精品影院 | 狠狠v欧美v日韩v亚洲ⅴ| 精品一区二区三区免费视频| 国产高清一区日本| 色婷婷精品久久二区二区蜜臀av| 欧美亚洲国产bt| 欧美一级一区二区| 国产精品欧美久久久久一区二区| 国产欧美日韩不卡| 亚洲精品五月天| 蜜桃精品在线观看| a级精品国产片在线观看| 日本久久精品电影| 欧美一级搡bbbb搡bbbb| 久久久久久黄色| 亚洲人成人一区二区在线观看| 亚洲成a人片综合在线| 美女看a上一区| 一本大道综合伊人精品热热 | 美女视频免费一区| 91视视频在线观看入口直接观看www | 中文一区二区完整视频在线观看| 国产精品三级视频| 免费久久精品视频| 国产午夜精品一区二区三区嫩草| 欧美性受xxxx黑人xyx性爽| 欧美成人欧美edvon| 一二三四社区欧美黄| 国内精品第一页| 欧美妇女性影城| 亚洲视频在线一区二区| 国产一区二区成人久久免费影院| 91论坛在线播放| 国产精品日韩成人| 国产做a爰片久久毛片| 欧美日本在线一区| 在线成人免费观看| 亚洲欧美aⅴ...| 国产高清无密码一区二区三区| 欧美一卡二卡三卡| 一区二区欧美在线观看| 粉嫩蜜臀av国产精品网站| 日韩视频在线永久播放| 丝袜a∨在线一区二区三区不卡| 色综合视频在线观看| 日韩一区二区三区免费观看| 中文字幕av免费专区久久| 国产毛片一区二区| 国产亚洲精品bt天堂精选| 亚洲一线二线三线视频| 欧美性大战xxxxx久久久| 亚洲国产精品一区二区久久| 国产美女在线观看一区| 激情偷乱视频一区二区三区| 国产乱人伦偷精品视频免下载 | 这里是久久伊人| 国产精品免费久久| 国产成人精品影院| 欧美一区二区在线播放| 最近日韩中文字幕| 99久久精品免费看国产免费软件| 中文字幕亚洲综合久久菠萝蜜| 精品综合久久久久久8888| 日韩视频一区二区三区在线播放| 日韩av一级片| 日韩欧美国产一区二区三区| www.日本不卡| 国产欧美精品日韩区二区麻豆天美| 午夜精品一区二区三区三上悠亚 | 欧美日韩一区 二区 三区 久久精品| 日韩欧美黄色影院| 国产精品资源网站| 久久久久9999亚洲精品| 日韩精品久久理论片| 久久精品人人爽人人爽| 国产尤物一区二区在线| 久久嫩草精品久久久久| 成人福利电影精品一区二区在线观看| 2020国产精品| 91丝袜高跟美女视频| 亚洲色图视频网站| 欧美一区二区三区在线| 国产精品一二三四五| 亚洲制服欧美中文字幕中文字幕| 91麻豆蜜桃一区二区三区| 亚洲成人精品在线观看| 国产午夜精品一区二区三区视频| 成人性视频网站| 亚洲小少妇裸体bbw| 在线播放中文一区| 懂色中文一区二区在线播放| 夜夜精品视频一区二区 | 国产+成+人+亚洲欧洲自线| 亚洲美女视频一区| 欧美一级高清大全免费观看| 乱中年女人伦av一区二区| 欧美刺激脚交jootjob| 国产乱子伦一区二区三区国色天香| 亚洲国产岛国毛片在线| 欧美三级日韩三级| 成人黄色综合网站| 亚洲1区2区3区4区| 亚洲欧美日韩国产综合在线 | 国产欧美日产一区| 日本久久一区二区三区| 麻豆久久久久久| 一个色综合av| 中文字幕国产一区二区| 91精品国产综合久久小美女| eeuss鲁片一区二区三区| 日韩高清在线不卡| 日韩理论片中文av|