網頁

2013年1月30日

如何避免Linux zombie process的產生?

Origin: 如何避免Linux zombie process的產生?

所謂zombie process(殭屍行程)的成因,在於某行程已結束,但其父行程(parent process)並未取得該行程之結束狀態,則該行程就會變成zombie process,直到其父行程呼叫wait()取得該行程結束狀態。

用更精確的說法,來自Advanced Programming in the Unix Environment這本書:
The process that has terminated, but whose parent hasn’t yet waited for it.

Zombie process會造成kernel內部有多餘的一筆process資料儲存,佔了一筆資料量(process id, termination status, the amount of CPU time taken by the process等等資訊),但其卻已經結束了,若是系統load很高,造成的影響就更大了,譬如process數量到達上限,又發生有zombie process,可能就會產生無法執行程式的問題。因此我們必須避免zombie process的產生。

正常的multiprocess程式執行的流程,如下圖所示,parent process必須wait其子行程的結束。

下圖的情形,則會產生zombie process:在A還沒wait或exit之前,若B已結束,則這段時間內B就是zombie process了。

該如何避免zombie process呢?或許google一下也知道吧!由於Linux會在一個process的父行程結束時,自動把該行程的父行程變成init,也就是讓該 process由init接管。

因此,假設我們的父行程必須作自己的事情,並不想wait子行程結束而block時,我們可以利用兩次fork,讓第一次 fork的process馬上結束,則第二次fork的grandchild將會自動變成init的子行程,這樣一來,最原先的行程將不必在作wait的動作,而該行程從此也跟第二次fork出來的行程毫無親屬關係了。兩者各作各的,誰先結束並不會影響對方。這就是fork兩次的用意:

 

如上圖所示,寫成程式大概會像是這樣(注意:裏面沒有錯誤處理的code):

if pid = fork()
    //parent waits for first child to exit
    waitpid(pid);
    parent does things here...
else
    //child
    if fork()
       //child
       exit;
    else
       //granchild
       grandchild does things here...

沒有留言:

張貼留言