停止docker,小議Linux中的僵死進程

 2023-11-19 阅读 22 评论 0

摘要:???? 在讀《unix環境高級編程》時,發現忽然對僵死進程的處理機制很感興趣,經過查閱資料弄清楚了其中的原理,在這里做一個記錄。 ???? 1.一個進程的離去 ???? 在一個進程調用? exit? 函數,或者? return? 語句,或者是調用? abort? 等函數終止

???? 在讀《unix環境高級編程》時,發現忽然對僵死進程的處理機制很感興趣,經過查閱資料弄清楚了其中的原理,在這里做一個記錄。

???? 1.一個進程的離去

???? 在一個進程調用? exit? 函數,或者? return? 語句,或者是調用? abort? 等函數終止后,總之不管進程是怎樣終止的,它們在終止之后,都會去執行內核中的一個代碼片斷。這個代碼片斷負責關閉終止進程打開的文件描述符,釋放終止進程占用的內存空間。但是,是否終止進程在系統中就從此消失,以后該進程在系統中,就再也找不到這個終止進程的一點蹤影呢,答案是否定的。

???? 2.僵死進程

???? 一個進程在終止之后,會釋放它所占用的一切資源。但是會在進程表中保留該進程的一些生前的信息,比如進程ID,進程使用的CPU時間,退出狀態等。這時這個終止進程的狀態就稱之為僵死狀態,它要等待它的父進程來為它收尸。這時候在? linux? 系統中,僵死進程的狀態被打印為? ‘Z’,它的父進程通過調用? wait? 或者是? waitpid? 函數來為其善后。

???? 3.動手做,理解僵死進程

停止docker、???? 僵死進程是怎么產生的呢?這是因為,在一個程序中,不斷的調用fork函數,卻沒有調用? wait? 或者? waitpid? 函數來做清除工作,而該程序又沒有終止,這樣就會在系統中產生僵死進程。解釋了這么多概念,不如給一個例子可能會更加的清晰,下面的一個例子用來在系統中產生僵死進程:

#include <stdio.h>
#include <unistd.h>int main(void)
{pid_t pid;while(1){if( (pid=fork())<0 ){printf("fork error\n");return -1;}else if( pid==0 ){printf("child\n");_exit(0);}else{sleep(1);}}return 0;
}   

將程序編譯完成之后,執行,會每隔1秒鐘產生一個子進程。在子進程中輸出提示信息? child? 之后就立即退出。這個程序在執行的時候,我們再開一個終端,輸入命令:

ps aux | grep 'Z'

可以看到輸出結果如下:
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
asus      3213  0.0  0.0      0     0 pts/0    Z+   20:54   0:00 [a.out] <defunct>
asus      3214  0.0  0.0      0     0 pts/0    Z+   20:54   0:00 [a.out] <defunct>
asus      3215  0.0  0.0      0     0 pts/0    Z+   20:54   0:00 [a.out] <defunct>
asus      3217  0.0  0.0      0     0 pts/0    Z+   20:54   0:00 [a.out] <defunct>
asus      3271  0.0  0.0      0     0 pts/0    Z+   20:54   0:00 [a.out] <defunct>
asus      3272  0.0  0.0      0     0 pts/0    Z+   20:54   0:00 [a.out] <defunct>
asus      3273  0.0  0.0      0     0 pts/0    Z+   20:54   0:00 [a.out] <defunct>
asus      3274  0.0  0.0      0     0 pts/0    Z+   20:54   0:00 [a.out] <defunct>
asus      3275  0.0  0.0      0     0 pts/0    Z+   20:54   0:00 [a.out] <defunct>
asus      3276  0.0  0.0      0     0 pts/0    Z+   20:54   0:00 [a.out] <defunct>
asus      3277  0.0  0.0      0     0 pts/0    Z+   20:54   0:00 [a.out] <defunct>
asus      3282  0.0  0.0      0     0 pts/0    Z+   20:54   0:00 [a.out] <defunct>
asus      3343  0.0  0.0      0     0 pts/0    Z+   20:54   0:00 [a.out] <defunct>
asus      3344  0.0  0.0      0     0 pts/0    Z+   20:54   0:00 [a.out] <defunct>

我們可以看到這些進程的STAT都為僵死進程。如果我們按? ctrl+c? 把執行的程序終止,再次執行這個命令,會發現在系統中所有產生的僵死進程都消失了。

Linux,???? 感覺很奇怪吧,既然這些僵死進程都消失了,那么就一定有一個進程為系統種的僵死進程收尸,這個進程就是? init? 進程,它的PID為1。原來在? linux? 中,當一個進程的父進程終止時,這個進程就成為了孤兒進程,那么? init? 進程就是一個好心的人了,它專門收養孤兒進程。而? init? 進程又被實現為,當它有一個子進程終止時,就立即調用? wait? 函數來善后。所以就我們剛才的例子來說,當我們把程序終止后,所有僵死進程的父進程就變成了? init,而? init? 發現,哦,原來你們都是僵死進程啊,所以它給每一個僵死進程調用? wait? 函數,是使它們能夠安心離去。init? 進程的這種實現方式使得? linux? 系統中的僵死進程不會太多。當然,如果這個程序永遠不終止,那么系統中的僵死進程就會越來越多。

??? 注意:一個僵死進程在內存中已經沒有程序的正文和數據,所以不能使用? kill? 來殺死一個僵死的進程。只能通過殺死僵死進程的父進程來清除僵死進程,或者在父進程中調用wait或waipid函數來清除。

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/4/183622.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息