Calvin's Tech Space

          成于堅(jiān)忍,毀于浮躁

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

          ps aux|grep defunct
          找出僵死進(jìn)程

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

          刪除僵尸進(jìn)程的根本方法是讓它的父進(jìn)程調(diào)用wait來處理SIGCHLD信號(hào)。有兩種方式可以做到這一點(diǎn)。一種方法是改變它的父進(jìn)程。可以用kill命令殺死它的父進(jìn)程,這樣init變成它的新的父進(jìn)程,而init會(huì)定時(shí)地執(zhí)行wait系統(tǒng)調(diào)用。另一種方式是使用調(diào)試器,在父進(jìn)程中執(zhí)行wait系統(tǒng)調(diào)用。如果知道了父進(jìn)程的程序名稱和它的進(jìn)程號(hào),運(yùn)行下面命令:

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

          gdb會(huì)在父進(jìn)程中調(diào)用wait,從而達(dá)到我們的目的。注意,unwindonsignal要被set為on, 它告訴gdb把堆棧恢復(fù)到調(diào)用wait之前的狀態(tài)。要不然父進(jìn)程會(huì)crash。 在程序中避免僵死進(jìn)程除了顯式調(diào)用wait或waitpid外,也可以使用下面的代碼來避免僵死進(jìn)程(這兒假設(shè)父進(jìn)程對(duì)子進(jìn)程的狀態(tài)不感興趣),它遵循POSIX,是可移植的。

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

          參考exit(2)手冊(cè)頁。
          posted on 2010-06-27 10:53 calvin 閱讀(731) 評(píng)論(0)  編輯  收藏 所屬分類: Linux
          主站蜘蛛池模板: 阳泉市| 讷河市| 波密县| 龙州县| 铜鼓县| 伊宁市| 桃源县| 栾城县| 嫩江县| 商河县| 大埔县| 延川县| 玛纳斯县| 古田县| 锦屏县| 察雅县| 罗定市| 沧州市| 科尔| 通海县| 梁平县| 通山县| 包头市| 江城| 咸阳市| 民县| 泗阳县| 娄烦县| 仲巴县| 涟水县| 开江县| 察哈| 宁化县| 东兰县| 福海县| 大港区| 东辽县| 上栗县| 常熟市| 南康市| 商河县|