殭屍進程(zombie process )

殭屍進程參照百度百科,及其部分論壇內容。
In UNIX System terminology, a process that has terminated,but whose parent has not yet waited for it, is called a zombie. 在UNIX 系統中,一個進程結束了,但是他的
父進程沒有等待(調用wait / waitpid)他, 那麼他將變成一個殭屍進程。
如果該進程的父進程已經先結束,那麼該進程就不會變成殭屍進程, 因爲系統進程Init 會自動接管他,成爲他的父進程。
殭屍進程(Zombie)可以認爲只是一種數據結構包括進程號the process ID,退出狀態the termination status of the process,運行時間the amount of CPU time taken by the process等進程結束時,內核釋放該進程佔用所有的資源,包括打開的文件,佔用的內存等,但是唯獨沒有釋放標識進程自身狀態信息的結構(PCB),即殭屍進程。
殭屍進程產生的原因:
UNⅨ提供了一種機制可以保證只要父進程想知道子進程結束時的狀態信息, 就可以得到。這種機制就是: 在每個進程退出的時候,內核釋放該進程所有的資源,包括打開的文件,佔用的內存等。但是仍然爲其保留一定的信息(包括進程號the process ID,退出狀態the termination status of the process,運行時間the amount of CPU time taken by the process等)。直到父進程通過wait / waitpid來取時才釋放. 但這樣就導致了問題,如果進程不調用wait / waitpid的話,那麼保留的那段信息就不會釋放,其進程號就會一直被佔用,從而產生殭屍進程。
系統所能使用的進程號是有限的,如果大量的產生僵死進程,將因爲沒有可用的進程號而導致系統不能產生新的進程. 此即爲殭屍進程的危害,應當避免。

殭屍進程的避免
父進程通過wait和waitpid等函數等待子進程結束,這會導致父進程掛起。
⒉ 如果父進程很忙,可以用signal函數爲SIGCHLD安裝handler,因爲子進程結束後, 父進程會收到該信號,可以在handler中調用wait回收。
如果父進程不關心子進程的結束,可以用signal(SIGCHLD,SIG_IGN) 通知內核,自己對子進程的結束不感興趣,那麼子進程結束後,內核會回收, 並不再給父進程發送信號。
⒋創建服務進程。 fork兩次,父進程fork一個子進程,然後繼續工作,子進程fork一 個孫進程後退出,那麼孫進程被init接管,孫進程結束後,init會回收。

註釋:
SIGCHLD屬於unix以及類unix系統的一種信號。
在一個進程終止或者停止時,將SIGCHLD信號發送給其父進程。按系統默認將忽略此信號。如果父進程希望被告知其子系統的這種狀態,則應捕捉此信號。信號的捕捉函數中通常調用wait函數以取得進程ID和其終止狀態。
備註:
On Unix and Unix-like computer operating systems, a zombie process or defunct process is a process that has completed execution but still has an entry in the process table. This entry is still needed to allow the parent process to read its child's exit status. The term zombie process derives from the common definition of zombie — an undead person. In the term's metaphor, the child process has "died" but has not yet been "reaped". Also, unlike normal processes, the kill command has no effect on a zombie process.

When a process ends, all of the memory and resources associated with it are deallocated so they can be used by other processes. However, the process's entry in the process table remains. The parent can read the child's exit status by executing the wait system call, whereupon the zombie is removed. The wait call may be executed in sequential code, but it is commonly executed in a handler for the SIGCHLD signal, which the parent receives whenever a child has died.

After the zombie is removed, its process identifier (PID) and entry in the process table can then be reused. However, if a parent fails to call wait, the zombie will be left in the process table. In some situations this may be desirable, for example if the parent creates another child process it ensures that it will not be allocated the same PID. On modern UNIX-like systems (that comply with SUSv3 specification in this respect), the following special case applies: if the parent explicitly ignores SIGCHLD by setting its handler to SIG_IGN (rather than simply ignoring the signal by default) or has the SA_NOCLDWAIT flag set, all child exit status information will be discarded and no zombie processes will be left.

A zombie process is not the same as an orphan process. An orphan process is a process that is still executing, but whose parent has died. They do not become zombie processes; instead, they are adopted by init (process ID 1), which waits on its children.

Zombies can be identified in the output from the Unix ps command by the presence of a "Z" in the "STAT" column.[1] Zombies that exist for more than a short period of time typically indicate a bug in the parent program, or just an uncommon decision to reap children (see example). If the parent program is no longer running, zombie processes typically indicate a bug in the operating system. As with other leaks, the presence of a few zombies is not worrisome in itself, but may indicate a problem that would grow serious under heavier loads. Since there is no memory allocated to zombie processes except for the process table entry itself, the primary concern with many zombies is not running out of memory, but rather running out of process ID numbers.

To remove zombies from a system, the SIGCHLD signal can be sent to the parent manually, using the kill command. If the parent process still refuses to reap the zombie, the next step would be to remove the parent process. When a process loses its parent, init becomes its new parent.Init periodically executes the wait system call to reap any zombies with init as parent.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章