Calvin's Tech Space

          成于堅忍,毀于浮躁

             :: 首頁 :: 聯系 :: 聚合  :: 管理
          僵死(Zombie)進程
          進程在它的生命周期有幾種狀態:睡眠,可運行,停止,正在運行和僵死狀態。所謂僵死進程,指的是一個進程已經退出,它的內存和相關的資源已經被內核釋放掉,但是在進程表中這個進程項(entry)還保留著,以便它的父進程得到它的退出狀態。一個進程退出時,它的父進程會收到一個SIGCHLD信號。一般情況下,這個信號的句柄通常執行wait系統調用,這樣處于僵死狀態的進程會被刪除。如果父進程沒有這么做,結果是什么呢?毫無疑問,進程會處于僵死狀態。實際上,僵死進程不會對系統有太大的傷害,最多就是它的進程號(PID)和進程表中的進程項系統不能使用。

          ps aux|grep defunct
          找出僵死進程

          注意用kill命令不能殺死這種進程。原因是它已經退出了,什么也沒有了,自然無法收到任何信號。

          刪除僵尸進程的根本方法是讓它的父進程調用wait來處理SIGCHLD信號。有兩種方式可以做到這一點。一種方法是改變它的父進程??梢杂胟ill命令殺死它的父進程,這樣init變成它的新的父進程,而init會定時地執行wait系統調用。另一種方式是使用調試器,在父進程中執行wait系統調用。如果知道了父進程的程序名稱和它的進程號,運行下面命令:

          %gdb `parent application name` `parent pid`
          (gdb) set unwindonsignal on
          (gdb) call wait(pid of zombie process)

          gdb會在父進程中調用wait,從而達到我們的目的。注意,unwindonsignal要被set為on, 它告訴gdb把堆?;謴偷秸{用wait之前的狀態。要不然父進程會crash。 在程序中避免僵死進程除了顯式調用wait或waitpid外,也可以使用下面的代碼來避免僵死進程(這兒假設父進程對子進程的狀態不感興趣),它遵循POSIX,是可移植的。

          struct sigaction sa;
          sa.sa_handler = SIG_IGN;
          sa.sa_flags = SA_NOCLDWAIT;
          sigemptyset (&sa.sa_mask);
          sigaction (SIGCHLD, &sa, NULL);

          參考exit(2)手冊頁。
          posted on 2010-06-27 10:53 calvin 閱讀(728) 評論(0)  編輯  收藏 所屬分類: Linux
          主站蜘蛛池模板: 合阳县| 乌兰浩特市| 阳东县| 油尖旺区| 靖安县| 武川县| 抚松县| 金堂县| 克什克腾旗| 开封市| 广州市| 宜昌市| 陇南市| 麻江县| 宁阳县| 舟山市| 荃湾区| 宾阳县| 张家港市| 梅河口市| 凤山市| 隆子县| 瓦房店市| 安阳市| 普洱| 罗田县| 辽阳市| 焦作市| 嘉禾县| 成安县| 濮阳市| 荥经县| 承德市| 禹州市| 闸北区| 都昌县| 镇平县| 凤凰县| 乐至县| 东莞市| 高青县|