日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

孤儿进程和僵尸进程

發布時間:2025/7/14 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 孤儿进程和僵尸进程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前幾天接到某互聯網公司的電話面試,面試官問我兩次fork()的作用,我一頭霧水,說不知道。知識面還是太窄了。下面就總結下兩次fork()的作用。

?

首先,要了解什么叫僵尸進程,什么叫孤兒進程,以及服務器進程運行所需要的一些條件。兩次fork()就是為了解決這些相關的問題而出現的一種編程方法。

?孤兒進程

??????? 孤兒進程是指父進程在子進程結束之前死亡(return 或exit)。如下圖1所示:

圖1? 孤兒進程

但是孤兒進程并不會像上面畫的那樣持續很長時間,當系統發現孤兒進程時,init進程就收養孤兒進程,成為它的父親,child進程exit后的資源回收就都由init進程來完成。

?

僵尸進程

???????? 僵尸進程是指子進程在父進程之前結束了,但是父進程沒有用wait或waitpid回收子進程。如下圖所示:

?????

圖2?? 僵尸進程

???????? 父進程沒有用wait回收子進程并不說明它不會回收子進程。子進程在結束的時候會給其父進程發送一個SIGCHILD信號,父進程默認是忽略SIGCHILD信號的,如果父進程通過signal()函數設置了SIGCHILD的信號處理函數,則在信號處理函數中可以回收子進程的資源。

????? 事實上,即便是父進程沒有設置SIGCHILD的信號處理函數,也沒有關系,因為在父進程結束之前,子進程可以一直保持僵尸狀態,當父進程結束后,init進程就會負責回收僵尸子進程。

????? 但是,如果父進程是一個服務器進程,一直循環著不退出,那子進程就會一直保持著僵尸狀態。雖然僵尸進程不會占用任何內存資源,但是過多的僵尸進程總還是會影響系統性能的。黔驢技窮的情況下,該怎么辦呢?

???????? 這個時候就需要一個英雄來拯救整個世界,它就是兩次fork()技法。

兩次fork()技法

???????? 兩次fork()的流程如下所示:

圖3??? 兩次fork的控制流

???????如上圖3所示,為了避免子進程child成為僵尸進程,我們可以人為地創建一個子進程child1,再讓child1成為工作子進程child2的父進程,child2出生后child1退出,這個時候child2相當于是child1產生的孤兒進程,這個孤兒進程由系統進程init回收。這樣,當child2退出的時候,init就會回收child2的資源,child2就不會成為孤魂野鬼禍國殃民了。

?

?? <unix環境高級編程>這本書里提供了兩次fork的一個例子,代碼如下:

[cpp]?view plaincopy
  • int?main(void)??
  • {??
  • ????pid_t????????pid;??
  • ??
  • ????if?(?(pid?=?fork())?<?0)??
  • ??????????err_sys("fork?error");??
  • ????else?if?(pid?==?0)???
  • ????????{????????????????/*?first?child?*/??
  • ???????????if?(?(pid?=?fork())?<?0)??
  • ????????????????????????err_sys("fork?error");??
  • ???????????else?if?(pid?>?0)??
  • ?????????????????exit(0);????????/*?parent?from?second?fork?==?first?child?*/??
  • ??
  • ????????????????/*?We're?the?second?child;?our?parent?becomes?init?as?soon?
  • ???????????????????as?our?real?parent?calls?exit()?in?the?statement?above.?
  • ???????????????????Here's?where?we'd?continue?executing,?knowing?that?when?
  • ???????????????????we're?done,?init?will?reap?our?status.?*/??
  • ??
  • ????????????sleep(2);??
  • ????????????printf("second?child,?parent?pid?=?%d\n",?getppid());??
  • ????????????exit(0);??
  • ????????}??
  • ??
  • ????if?(waitpid(pid,?NULL,?0)?!=?pid)????????/*?wait?for?first?child?*/??
  • ????????????err_sys("waitpid?error");??
  • ??
  • ????????/*?We're?the?parent?(the?original?process);?we?continue?executing,?
  • ???????????knowing?that?we're?not?the?parent?of?the?second?child.?*/??
  • ??
  • ????exit(0);??
  • }??
  • ???????理所當然,第二個子進程的父進程是進程號為1的init進程。??
  • ?????????一言以蔽之,兩次fork()是人為地創建一個工作子進程的父進程,然后讓這個人為父進程退出,之后工作子進程就由init回收,避免了工作子進程成為僵尸進程。

    轉載于:https://www.cnblogs.com/cobbliu/archive/2012/03/10/2388565.html

    總結

    以上是生活随笔為你收集整理的孤儿进程和僵尸进程的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。