為什麼fork()2次會避免產生殭屍程序
阿新 • • 發佈:2019-01-29
什麼是殭屍程序:用fork()建立子程序後,子程序已終止但父程序沒有對它進行善後處理,那麼子程序的程序描述符就一直儲存在記憶體中,子程序就是殭屍程序。
怎麼產生殭屍程序:
1.父程序沒有SIGCHLD訊號處理函式,也就是沒有呼叫wait()/waitpid()來獲取子程序的退出狀態,也就沒存對程序描述符進行處理。
2.父程序有呼叫wait()/waitpid()函式,但當子程序已終止時父程序還沒有執行到wait()/waitpid()函式這一步,此時子程序也時殭屍程序。
怎麼避免產生殭屍程序:
1.父程序呼叫wait()/waitpid()函式,還要保證在子程序結束前父程序已執行到wait()/waitpid()這一步。
2.父程序先終止,子程序變成了孤兒程序,由init程序收養(pid=1),當子程序終止時,init程序會對子程序進行處理。
避免產生殭屍程序的方法:fork()2次。
1.父程序fork()後產生一個子程序,隨後就立即執行waitpid()/wait()函式來等待子程序結束。
2.然後子程序fork()後產生一個孫子程序,立即執行exit(0)結束子程序,然後父程序繼續指向,由於孫子程序失去了它的父程序,那麼孫子程序變為孤兒程序。
3.孫子程序先要指行sleep(n)這步操作,否則他可能會比他的父程序先指行,那麼打印出來的ID是建立它的ID,而不是init的ID,因為在作業系統中父子程序執行的先後順序不能確定。
4.這樣孫子程序來執行它父程序需要的事件,而不會有殭屍程序出現。(父子程序共享程式碼段)
#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<sys/types.h> int main() { pid_t id1=fork(); if(id1==0)//child { pid_t id2=fork(); //避免殭屍程序 if(id2>0) //father 直接退出 { exit(0); } else { sleep(2); //保證他的父程序先執行 printf("second child de father id=%d\n",getppid()); //他會成為孤兒程序,1號程序將會收養他 exit(0); } } else //father { waitpid(id1,NULL,0); //立即來等待子程序結束 } return 0; }