免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
服務(wù)器進(jìn)程為何通常fork()兩次
前幾天接到某互聯(lián)網(wǎng)公司的電話面試,面試官問我兩次fork()的作用,我一頭霧水,說不知道。知識面還是太窄了。下面就總結(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)。如下圖所示:

但是孤兒進(jìn)程并不會像上面畫的那樣持續(xù)很長時間,當(dāng)系統(tǒng)發(fā)現(xiàn)孤兒進(jìn)程時,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)程。如下圖所示:

     

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

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

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

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

兩次fork()技法

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

《UNIX環(huán)境高級編程》(下載見http://www.linuxidc.net/thread-2063-1-1.html)這本書里提供了兩次fork的一個例子,代碼如下:

  1. int main(void)  
  2. {  
  3.     pid_t        pid;  
  4.   
  5.     if ( (pid = fork()) < 0)  
  6.           err_sys("fork error");  
  7.     else if (pid == 0)   
  8.         {                /* first child */  
  9.            if ( (pid = fork()) < 0)  
  10.                         err_sys("fork error");  
  11.            else if (pid > 0)  
  12.                  exit(0);        /* parent from second fork == first child */  
  13.   
  14.                 /* We're the second child; our parent becomes init as soon 
  15.                    as our real parent calls exit() in the statement above. 
  16.                    Here's where we'd continue executing, knowing that when 
  17.                    we're done, init will reap our status. */  
  18.   
  19.             sleep(2);  
  20.             printf("second child, parent pid = %d\n", getppid());  
  21.             exit(0);  
  22.         }  
  23.   
  24.     if (waitpid(pid, NULL, 0) != pid)        /* wait for first child */  
  25.             err_sys("waitpid error");  
  26.   
  27.         /* We're the parent (the original process); we continue executing, 
  28.            knowing that we're not the parent of the second child. */  
  29.   
  30.     exit(0);  
  31. }  

理所當(dāng)然,第二個子進(jìn)程的父進(jìn)程是進(jìn)程號為1的init進(jìn)程。

 一言以蔽之,兩次fork()是為了防止系統(tǒng)中產(chǎn)生僵尸進(jìn)程。 

參考文獻(xiàn):《UNIX環(huán)境高級編程》下載見http://www.linuxidc.net/thread-2063-1-1.html 與 http://www.linuxidc.com/Linux/2011-04/34662.htm

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
孤兒進(jìn)程和僵尸進(jìn)程
Linux中產(chǎn)生zombie的原因是什么?
孤兒進(jìn)程與僵尸進(jìn)程[總結(jié)]
fork兩次如何避免僵尸進(jìn)程收藏
Linux僵尸進(jìn)程詳解
PHP多進(jìn)程編程 - 井長 - Jason Yu
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服