大家好大安,我是良旭。在本文中,我们将讨论什么是僵尸进程,僵尸进程是如何产生的,以及如何杀死僵尸进程。Linux中的进程是什么?说到进程,我们需要了解另一个概念:程序。说白了,程序就是一个躺在电脑硬盘上的文件(就像硬盘女神一样),在被CPU执行之前,它什么也做不了。当程序执行时,它运行的实例称为进程。一个程序可以对应多个进程。进程是系统的工作单元。系统由多个进程组成,其中一些是操作系统进程(执行系统代码),另一些是用户进程(执行用户代码)。所有这些进程都是并发执行的,例如通过在单个CPU上使用多路复用。您可以使用ps命令查看Linux系统中的所有进程。$ps-axPIDTTY统计时间命令1?Ss0:01/usr/lib/systemd/systemdrhgb--switched-root--sys2?S0:00[kthreadd]3?我<0:00[rcu_gp]4?I<0:00[rcu_par_gp]当一个进程调用fork函数生成另一个进程时,原来的进程称为父进程,新生成的进程称为子进程。Linux系统中有这么多这样的父子进程,我们可以使用pstree命令查看系统上的进程“谱系”。$pstree-psnsystemd(1)─┬─systemd-journal(952)├─systemd-udevd(963)├─systemd-oomd(1137)├─systemd-resolve(1138)├─systemd-userdbd(1139)─┬─systemd-userwor(12707)│├─systemd-userwor(12714)│└─systemd-userwor(12715)├─auditd(1140)────{auditd}(1141)├─dbus-broker-lau(1164)────dbus-broker(1165)├─avahi-daemon(1166)────avahi-daemon(1196)├─bluetoothd(1167)每个进程在系统中都分配了一个编号。在所有这些进程中,有一个非常特殊的进程,其ID号为1,它是系统启动时第一个执行的进程,PID为1之后的每一个后续进程都是它的后代。什么是僵尸进程?前面提到,在Linux环境下,我们使用fork函数来创建子进程。创建完成后,父子进程独立运行,父进程无法预测子进程何时结束。通常,子进程退出后,父进程会使用wait或waitpid函数回收子进程的资源,获取子进程的终止状态。但是,如果父进程在子进程之前结束,则子进程成为孤儿进程。孤儿进程会被init进程(进程号1)收养,init进程会完成对孤儿进程的状态收集工作。而如果子进程先于父进程退出,同时父进程太忙,则完美回收子进程的资源,将子进程的剩余资源(PCB)存放在内核中,变成僵尸进程,如下图:Zombie进程是怎么来的?上面已经介绍了僵尸进程生成的原理。接下来,我们将通过代码模拟僵尸进程的产生。#include#include#include#includeintmain(void){pid_tpid;pid=fork();if(pid==0){printf("我是孩子,我的父母=%d,要睡3s\n",getppid());睡觉(3);printf("------------孩子死了------------\n");}elseif(pid>0){printf("我是父母,pid=%d,myson=%d,goingtosleep5s\n",getpid(),pid);睡觉(5);system("ps-opid,ppid,state,tty,command");}else{perror("fork");返回1;}返回0;}在这个程序中,父进程创建子进程后,会休眠5秒。子进程在退出前只休眠3秒。它退出后,父进程还没有被唤醒,所以没有人“收”子进程,于是就变成了僵尸进程。如何杀死僵尸进程对于正常进程,我们可以使用kill命令来杀死它们。kill命令有几个兄弟,比如pkill和killall。虽然它们的名字中都有kill这样的杀气腾腾的字眼,但它们实际上是为了向一个或多个进程发送信号而设??计的。如果未指定,这些命令默认发送SIGTERM信号。可以杀死普通进程,但僵尸进程不能。为什么?因为僵尸进程本身已经“死”过一次了!如果能再“死”一次,那“丧尸”这个名字也没什么意思。僵尸进程实际上是一个退出的进程,所以不能使用kill命令杀死僵尸进程。僵尸进程的罪魁祸首是父进程没有回收它的资源,那么我们可以想办法让其他进程回收僵尸进程的资源,这个进程就是init进程。因此,我们可以直接杀掉父进程,init进程会好心收养那些僵尸进程,合理回收它们的资源,那些僵尸进程就会得到妥善处理。例如,如果PID5878是一个僵尸进程,其父进程是PID4809,那么要杀死僵尸进程(5878),您将结束父进程(4809):$sudokill-94809#4809istheparent,notBe僵尸杀父进程的时候要小心,如果一个进程的父进程是PID1,你也杀了它,那么系统会直接重启!这将是一个更可怕的故事!最后,最近有很多朋友找我要一份Linux学习路线图,所以我结合自己的经验,利用业余时间熬夜一个月,整理了一本电子书。无论你是面试还是自我提升,相信都会对你有所帮助!免费送给大家,只求大家给我点个赞!电子书|LinuxDevelopmentLearningRoadmap也希望有小伙伴可以加入我的行列,把这本电子书做得更加完美!获得?希望老铁们来个三连击,让更多人看到这篇文章。推荐阅读:干货|程序员进阶架构师必备资源免费书单|程序员必读经典书籍清单(高清PDF版))
