精选文章 僵尸进程可以被“杀死”吗?

僵尸进程可以被“杀死”吗?

作者:QQ2651401966 时间: 2019-11-05 08:10:48
QQ2651401966 2019-11-05 08:10:48

僵尸不可能被杀死,因为它已经死了,不存在再死一次的问题。死的对立面是活,死者已死。只有活的进程才可能被杀死。

什么是僵尸

首先要明确一点,僵尸进程的含义是:子进程已经死了,但是父进程还没有wait它的一个中间状态,这个时候子进程是一个僵尸。正常情况下子死,父wait,清理掉子进程的task_struct,释放子进程的PID:

僵尸进程可以被“杀死”吗?1

编译上述程序,运行,我们看到2个a.out进程:

僵尸进程可以被“杀死”吗?2

杀死子进程4578,看到父进程的打印:

僵尸进程可以被“杀死”吗?3

之后,4578会消失,因为父进程执行到了wait,也知道了子进程是被信号2杀掉的。

但是如果子进程死了,父进程不执行到wait,比如把上图中的"#if 0"改为"#if 1",杀死子进程后,子进程就会是一个僵尸:

僵尸进程可以被“杀死”吗?4

我们重新运行,当我们用kill -2杀掉子进程4628后,我们发现4628成为一个僵尸,状态变为Z+,名字上也加了一个棺材[],成为[a.out]:

僵尸进程可以被“杀死”吗?5

僵尸不可能被杀死

我们看到上面4628是个僵尸很不爽,所以我们想把它干掉,据说Linux有个信号9,神挡杀神,佛挡杀佛,我们现在来用kill -9干掉4628:

僵尸进程可以被“杀死”吗?6

从上图可以看出,我们把4628用kill -9捅了好多刀,但是最后看4628这个僵尸,还是没有消失。

因为僵尸已经是死了,它不可能再次被杀死,你给它捅一万刀,它也是个死人,不可能再次死!

僵尸不可能被杀死,因为它已经死了!只等父进程来wait清理尸体了。

这个时候我们能够把僵尸消失掉的方法,就是杀死僵尸进程的父进程4627。

一个僵尸可以被杀死的假象

下面的这个程序证明“僵尸可以被杀死”

僵尸进程可以被“杀死”吗?7

我们在主线程里面,pthread_create()创建线程后,pthread_exit()退出,这个时候我们会发现,在ps命令里面,a.out显示为一个僵尸:

僵尸进程可以被“杀死”吗?8

这个时候我们来杀死4730这个僵尸:

kill -9 4730

我们会惊奇地发现,4730真地会从ps命令里面消失!

僵尸进程可以被“杀死”吗?9

我们把时间轴拉回调用"kill -9 4730"之前。刚才我们“看起来”能杀死僵尸的本质原因是,当主线程4730调用pthread_exit()退出后,主线程4730的状态确实是僵尸了,但是该进程里面的4731线程,却没有死:

僵尸进程可以被“杀死”吗?10

4731是活着的,证明整个进程并没有挂。所以4730的退出,只是让整个进程半死。而由于ps这些命令的误会,4730凑巧又是整个进程的PID,它显示地好像整个4370成了僵尸一样。

僵尸进程可以被“杀死”吗?11

那么,根据POSIX标准关于信号(signal)的定义,当我们执行kill -9 4730(4730是4730和4731的TGID,也是整个进程用户态视角的PID)的时候,是要杀死整个4730进程的,所以这个时候4731被我们杀死,整个进程就都死了,这个时候,执行到父进程的wait逻辑,导致僵尸消失。

所以,在本例中,kill -9 4730看起来是"杀死了僵尸”,实际是杀死了4730整个进程(里面的每个线程),导致整个进程死。在次之前,整个进程实际还是活的。

 

 

 

 

 

 

 

 

 

 

 

勿删,copyright占位
分享文章到微博
分享文章到朋友圈

上一篇:ping容易忽略的10点用法和排查问题技巧

下一篇:Feign整合Ribbon和Hystrix源码解析

您可能感兴趣

  • LINUX内核入门学习之路——LINUX进程调度

    一、Linux进程调度的目标 1.高效性:高效意味着在相同的时间下要完成更多的任务。调度程序会被频繁的执行,所以调度程序要尽可能的高效; 2.加强交互性能:在系统相当的负载下,也要保证系统的响应时间; 3.保证公平和避免饥渴; 4.SMP调度:调度程序必须支持多处理系统; 5.软实时调度:系统必须有效的调用实时进程,但不保证一定满足其要求; 二、Linux进程优先级 进程提供了两种优先级,一...

  • CPU 阿甘之烦恼

    1、批处理系统 CPU阿甘最近很烦。 原因很简单,内存和硬盘看他不顺眼。 (码农翻身注: 不认识阿甘的参见文章《CPU阿甘》) 阿甘心里很清楚, 是自己干活太快了,干完了活就歇着喝茶,这时候内存和硬盘还在辛辛苦苦的忙活,他们肯定觉得很不爽了。  中国有句古话叫什么来着? “木秀于林,风必摧之”,“不患贫而患不均”,这就是阿甘的处境。  虽然阿甘自己也于心不忍, 可是有什么办法?谁让他们那么慢...

  • Linux 进程管理数据结构

    文末集赞留言抽奖,我会选出留言点赞数前 3 名送出小米耳机。 别刷赞啊,刷赞被举报无效,相信真的是公众号粉丝的读者,不会做这样的行为,刷赞指的是购买外挂刷,如果是转发到朋友圈和微信群的,不算刷赞行为。 数据结构 Linux 内核使用 task_struct 来表示一个进程,这个结构体里面保存了进程的所有信息,要研究进程的数据结构,我就就需要研究这个结构体里面各个成员的作用。 struct t...

  • 宋宝华: 僵尸进程的成因以及僵尸可以被“杀死”吗?

    僵尸不可能被杀死,因为它已经死了,不存在再死一次的问题。死的对立面是活,死者已死。只有活的进程才可能被杀死。 什么是僵尸 首先要明确一点,僵尸进程的含义是:子进程已经死了,但是父进程还没有wait它的一个中间状态,这个时候子进程是一个僵尸。正常情况下子死,父wait,清理掉子进程的task_struct,释放子进程的PID: 编译上述程序,运行,我们看到2个a.out进程: 杀死子进程457...

  • 清华大学操作系统公开课(六)进程管理

    1.进程定义 进程和程序的区别在哪?一般我们把一个程序的一次运行叫做一个进程,粗略的说没什么太大区别,只是后来计算机内能跑很多个程序,有可能同时运行多次一个程序,这样用进程的概念可以区分不同的运行状态。 进程定义:一个具有一定独立功能的程序在一个数据集合上的一次动态执行过程。 可以看到,刚开始通过将源代码文件进行编译链接,变成了静态的可执行文件,只有当我们的系统将这段程序调入到内存中去,CP...

  • Kafka | Java 消费者是如何管理TCP连接的? | 极客时间

    今天我要和你分享的主题是:Kafka 的 Java 消费者是如何管理 TCP 连接的。 在专栏中,我们专门聊过“Java生产者是如何管理 TCP 连接资源的”这个话题,你应该还有印象吧?今天算是它的姊妹篇,我们一起来研究下 Kafka 的 Java消费者管理 TCP 或 Socket 资源的机制。只有完成了今天的讨论,我们才算是对 Kafka 客户端的 TCP 连接管理机制有了全面的了解。 ...

  • 线程操作函数

    线程控制原语:对线程控制的函数 连接编译时需要加参数: -lpthread pthread_self函数 获取线程ID。其作用对应进程中 getpid() 函数。 pthread_t pthread_self(void); 返回值:成功:0; 失败:无! 线程ID:pthread_t类型,本质:在Linux下为无符号整数(%lu),其他系统中可能是结构体实现 线程ID是进程内部,识别标志。(...

  • Linux命令系列--监管类命令

    其他网址 Linux系统管理(进程管理、工作管理和系统定时任务) ps 示例及选项 格式:ps [options] 示例 命令 作用 ps aux 显示所有进程的内存使用情况 ps -le 查看所有进程,而且还能看到进程的父进程的 PID 和进程优先级; ps -l 显示自己登陆的pid的信息 ps aux --sort -rss |head -n 20 将所有的进程按照rss进行排序(从上...

华为云40多款云服务产品0元试用活动

免费套餐,马上领取!
CSDN

CSDN

中国开发者社区CSDN (Chinese Software Developer Network) 创立于1999年,致力为中国开发者提供知识传播、在线学习、职业发展等全生命周期服务。