日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

孤儿进程和僵尸进程

發(fā)布時(shí)間:2025/7/14 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 孤儿进程和僵尸进程 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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

?

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

?孤兒進(jìn)程

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

圖1? 孤兒進(jìn)程

但是孤兒進(jìn)程并不會(huì)像上面畫的那樣持續(xù)很長(zhǎng)時(shí)間,當(dāng)系統(tǒng)發(fā)現(xiàn)孤兒進(jìn)程時(shí),init進(jìn)程就收養(yǎng)孤兒進(jìn)程,成為它的父親,child進(jìn)程exit后的資源回收就都由init進(jìn)程來完成。

?

僵尸進(jìn)程

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

?????

圖2?? 僵尸進(jìn)程

???????? 父進(jìn)程沒有用wait回收子進(jìn)程并不說明它不會(huì)回收子進(jìn)程。子進(jìn)程在結(jié)束的時(shí)候會(huì)給其父進(jìn)程發(fā)送一個(gè)SIGCHILD信號(hào),父進(jìn)程默認(rèn)是忽略SIGCHILD信號(hào)的,如果父進(jìn)程通過signal()函數(shù)設(shè)置了SIGCHILD的信號(hào)處理函數(shù),則在信號(hào)處理函數(shù)中可以回收子進(jìn)程的資源。

????? 事實(shí)上,即便是父進(jìn)程沒有設(shè)置SIGCHILD的信號(hào)處理函數(shù),也沒有關(guān)系,因?yàn)樵诟高M(jìn)程結(jié)束之前,子進(jìn)程可以一直保持僵尸狀態(tài),當(dāng)父進(jìn)程結(jié)束后,init進(jìn)程就會(huì)負(fù)責(zé)回收僵尸子進(jìn)程。

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

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

兩次fork()技法

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

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

???????如上圖3所示,為了避免子進(jìn)程child成為僵尸進(jìn)程,我們可以人為地創(chuàng)建一個(gè)子進(jìn)程child1,再讓child1成為工作子進(jìn)程child2的父進(jìn)程,child2出生后child1退出,這個(gè)時(shí)候child2相當(dāng)于是child1產(chǎn)生的孤兒進(jìn)程,這個(gè)孤兒進(jìn)程由系統(tǒng)進(jìn)程init回收。這樣,當(dāng)child2退出的時(shí)候,init就會(huì)回收child2的資源,child2就不會(huì)成為孤魂野鬼禍國(guó)殃民了。

?

?? <unix環(huán)境高級(jí)編程>這本書里提供了兩次fork的一個(gè)例子,代碼如下:

[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);??
  • }??
  • ???????理所當(dāng)然,第二個(gè)子進(jìn)程的父進(jìn)程是進(jìn)程號(hào)為1的init進(jìn)程。??
  • ?????????一言以蔽之,兩次fork()是人為地創(chuàng)建一個(gè)工作子進(jìn)程的父進(jìn)程,然后讓這個(gè)人為父進(jìn)程退出,之后工作子進(jìn)程就由init回收,避免了工作子進(jìn)程成為僵尸進(jìn)程。

    轉(zhuǎn)載于:https://www.cnblogs.com/cobbliu/archive/2012/03/10/2388565.html

    總結(jié)

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

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。