日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux 僵尸进程可以被杀死吗?

發布時間:2023/12/20 linux 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux 僵尸进程可以被杀死吗? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在 Unix 進程模型中,父進程和其所產生的子進程是異步運行的,所以如果子進程在結束后,會留下一些信息需要父進程使用 ?wait ?/ ?waitpid ?來接收。而如果父進程太忙了,沒有調用 ?wait ?/ ?waitpid ?的話,子進程就會變成僵尸進程

僵尸進程不可能被殺死,因為它已經死了,不存在再死一次的問題。死的對立面是活,死者已死。只有活的進程才可能被殺死。

什么是僵尸進程?

首先要明確一點,僵尸進程的含義是:子進程已經死了,但是父進程還沒有wait它的一個中間狀態,這個時候子進程是一個僵尸。正常情況下子死,父wait,清理掉子進程的task_struct,釋放子進程的PID:

#include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <semaphore.h>int main(void) {pid_t pid,wait_pid;int status;pid = fork();if(pid == 1){perror("Cannot create new process\n");exit(1);}else if(pid == 0){printf("child process id:%ld\n",(long)getpid());pause();_exit(0);}else{#if 0printf("ppid :%d\n",getpid());while(1);#endifdo{wait_pid = waitpid(pid,&status,WUNTRACED | WCONTINUED);if(WIFEXITED(status))printf("child process is killed by signal %d\n",WIFSIGNALED(status));}while(!WIFEXITED(status) && !WIFSIGNALED(status));exit(0);} }

執行

gcc ps_wait.c -pthread && ./a.out

執行情況如下

linux@ubuntu:~/linux$ gcc ps_wait.c -pthread && ./a.out child process id:4578

每次執行生成的子進程會不同,這里只是舉例子說明

運行,我們看到2個a.out進程

殺死子進程4578,看到父進程的打印:

之后,4578會消失,因為父進程執行到了wait,也知道了子進程是被信號2殺掉的。但是如果子進程死了,父進程不執行到wait,比如把上圖中的"#if 0"改為"#if 1",殺死子進程后,子進程就會是一個僵尸:

注意,這里說的是子進程會變成一個僵尸進程

代碼如下:

#include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <semaphore.h>int main(void) {pid_t pid,wait_pid;int status;pid = fork();if(pid == 1){perror("Cannot create new process\n");exit(1);}else if(pid == 0){printf("child process id:%ld\n",(long)getpid());pause();_exit(0);}else{#if 1printf("ppid :%d\n",getpid());while(1);#endifdo{wait_pid = waitpid(pid,&status,WUNTRACED | WCONTINUED);if(WIFEXITED(status))printf("child process is killed by signal %d\n",WIFSIGNALED(status));}while(!WIFEXITED(status) && !WIFSIGNALED(status));exit(0);} }

我們重新運行,當我們用kill -2殺掉子進程4628后,我們發現4628成為一個僵尸,狀態變為Z+,名字上也加了一個棺材[],成為[a.out]

Z表示的是僵尸進程,[]符號就像一口棺材一樣,把這個僵尸進程給裝了起來

僵尸不可能被殺死?

我們看到上面4628是個僵尸很不爽,所以我們想把它干掉,據說Linux有個信號9,神擋殺神,佛擋殺佛,我們現在來用kill -9干掉4628

從上圖可以看出,我們把4628用kill -9捅了好多刀,但是最后看4628這個僵尸,還是沒有消失。

因為僵尸已經是死了,它不可能再次被殺死,你給它捅一萬刀,它也是個死人,不可能再次死!

僵尸不可能被殺死,因為它已經死了!

兩種方法來清理僵尸進程1、只等父進程來wait清理尸體了2、這個時候我們能夠把僵尸消失掉的方法,就是殺死僵尸進程的父進程4627。

一個僵尸可以被殺死的假象

下面的這個程序證明「僵尸可以被殺死」這樣的假象。

#include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <semaphore.h>static void *thread_fun(void *param) {while(1); }int main(void) {pthread_t tid;int ret;ret = pthread_create(&tid,NULL,thread_fun,NULL);if(ret == -1){perror("cannot create new thread\n");return -1;}pthread_exit(0);return 0; }

我們在主線程里面,pthread_create()創建線程后,pthread_exit()退出,這個時候我們會發現,在ps命令里面,a.out顯示為一個僵尸進程。這個僵尸進程出現是我們在thread_fun 里面寫了一個while(1)不能退出導致的。

繼續,開始我們的表演,我們使用下面的命令來殺死這個僵尸進程。

kill -9 4730

我們會驚奇地發現,4730真地會從ps命令里面消失

在沒有執行命令殺死 4730 之前,我們「猜測」能殺死僵尸的本質原因是,當主線程4730調用pthread_exit()退出后,主線程4730的狀態確實是僵尸了,但是該進程里面的4731線程,卻沒有死。

我們看看proc 文件系統下面的進程狀態

看看4731:

4731是活著的,證明整個進程并沒有掛。所以4730的退出,只是讓整個進程半死。而由于ps這些命令的誤會,4730湊巧又是整個進程的PID,它顯示地好像整個4370成了僵尸一樣。

4731這個子進程什么時候死了呢?那么,根據POSIX標準關于信號(signal)的定義,當我們執行kill -9 4730 (4730是4730和4731的TGID,也是整個進程用戶態視角的PID)的時候,是要殺死整個4730進程的,所以這個時候4731被我們殺死,整個進程就都死了,這個時候,執行到父進程的wait邏輯,導致僵尸消失。

所以,在本例中,kill -9 4730看起來是"殺死了僵尸”,實際是殺死了4730整個進程(里面的每個線程),導致整個進程死。在此之前,整個進程實際還是活的。


掃碼或長按關注

回復「籃球的大肚子」進入技術群聊


創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的Linux 僵尸进程可以被杀死吗?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。