fork函式_例項(3)呼叫兩次以避免僵死程序
阿新 • • 發佈:2018-12-16
--------參考文獻 W.Richard Stevens, Stephen A.Rago.UNIX環境高階程式設計[M].北京:人民郵電出版社,2014.6:189-190.
一、 相關概念
1.1 僵死程序
一個已經終止,但是其父程序尚未對其進行善後處理(獲取終止子程序的有關資訊、釋放它仍佔用的資源)的程序被稱為僵死程序(zombie)。ps(1)命令將僵死程序的狀態列印為Z。如果編寫一個長期執行的程式,它fork了很多子程序,那麼除非父程序等待取得子程序的終止狀態,不然這些子程序終止後就會變成僵死程序。
帶來的問題就是——父程序不對終止的子程序進行處理(子程序太多,處理不過來),子程序會佔用資源直到父程序終止!這是一個極大的浪費。
1.2 init程序
init被編寫成無論何時只要有一個子程序終止,init就會呼叫wait函式取得其終止狀態。這樣也就防止了在系統中塞滿僵死程序。
二、 處理辦法
2.1 思路
fork兩次以避免僵死程序。如果一個程序fork一個子程序,但不要它等待子程序終止(不去管子程序),也不希望子程序處於僵死狀態直到父程序終止(僵死後光佔用資源沒有處理事務)。能否實現子程序不需要父程序管理但是會自動去進行善後?父程序結束,僵死子程序們會被init程序收養——這是自然的!有沒有什麼辦法?父程序沒有結束,父程序建立的子程序們手動交付給init程序,這樣的話,創建出來的子程序就不需要父程序去負責管理了。
如圖1 所示,通過這一層間接性,就實現避免僵死程序。
2.2 程式碼實現
#include<stdlib.h> //exit() #include<sys/wait.h> //waitpid() #include<stdio.h> //printf() int main() { pid_t pid; pid = fork(); if(pid < 0) printf("fork error!\n"); else if(0 == pid){ //first chld pid = fork(); if(pid < 0) printf("fork error!\n"); else if(pid > 0) exit(0); /*parent from second fork == first chld*/ /* * We're the second chld; our parent becomes init as soon * as out real parent calls exit() in the statement above, * Here's where we'd continue executing, knowing that when * we're done, init will reap out status. */ sleep(2); printf("second chld, parent pid = %ld\n", (long)getppid()); exit(0); } if(waitpid(pid, NULL, 0) != pid) /*wait for the first chld*/ printf("waitpid error!\n"); /* * We're the parent(the orginal process); we continue executing, * knowing that we're not the parent of the second chld. */ exit(0); }