在 unix 或 unix-like 的系統中,當一個子進程退出后,它就會變成一個僵尸進程,如果父進程沒有通過 wait 系統調用來讀取這個子進程的退出狀態的話,這個子進程就會一直維持僵尸進程狀態。
Zombie process - Wikipedia 中是這樣描述的:
On Unix and Unix-like computer operating systems, a zombie process or defunct process is a process that has completed execution (via the exit system call) but still has an entry in the process table: it is a process in the "Terminated state". This occurs for child processes, where the entry is still needed to allow the parent process to read its child's exit status: once the exit status is read via the wait system call, the zombie's entry is removed from the process table and it is said to be "reaped". A child process always first becomes a zombie before being removed from the resource table. In most cases, under normal system operation zombies are immediately waited on by their parent and then reaped by the system – processes that stay zombies for a long time are generally an error and cause a resource leak.
并且僵尸進程無法通過 kill 命令來清除。
本文將探討如何手動制造一個僵尸進程以及清除僵尸進程的辦法。
手動制造一個僵尸進程
為了便于后面講解清除僵尸進程的方法,我們使用日常開發中經常使用的 multiprocessing 模塊來制造僵尸進程(準確的來說是制造一個長時間維持僵尸進程狀態的子進程): 
$ cat test_a.pyfrom multiprocessing import Process, current_processimport loggingimport osimport timelogging.basicConfig(  level=logging.DEBUG,  format='%(asctime)-15s - %(levelname)s - %(message)s')def run():  logging.info('exit child process %s', current_process().pid)  os._exit(3)p = Process(target=run)p.start()time.sleep(100)測試:
$ python test_a.py &[1] 10091$ 2017-07-20 21:28:14,792 - INFO - exit child process 10106$ ps aux |grep 10106mozillazg 10126 0.0 0.0 2434836 740 s006 R+ 0:00.00 grep 10106mozillazg 10106 0.0 0.0 0 0 s006 Z 0:00.00 (Python)
可以看到,子進程 10091 變成了僵尸進程。
既然已經可以控制僵尸進程的產生了,那我們就可以進入下一步如何清除僵尸進程了。
清除僵尸進程有兩種方法:
•第一種方法就是結束父進程。當父進程退出的時候僵尸進程隨后也會被清除。
• 第二種方法就是通過 wait 調用來讀取子進程退出狀態。我們可以通過處理 SIGCHLD 信號,在處理程序中調用 wait 系統調用來清除僵尸進程。
處理 SIGCHLD 信號
子進程退出時系統會向父進程發送 SIGCHLD 信號,父進程可以通過注冊 SIGCHLD 信號處理程序,在信號處理程序中調用 wait 
系統調用來清理僵尸進程。 $ cat test_b.py
            
新聞熱點
疑難解答