如何杀死僵尸进程

“僵尸进程”是Linux系统中常见的一种无效进程,因为无效所以要清除掉。本篇文章分享了如何使用ps命令以及kill命令查找Linux僵尸进程和杀死Linux僵尸进程。
僵尸进程也被称为“无效”进程–简单来说,僵尸进程是已失效但存在于系统进程表中的进程。理想情况下,它应该在完成作业/执行后从进程表中清除掉,但是由于某种原因,其父进程在执行后不能正确清除它。

Linux僵尸进程是如何产生的

在Linux的世界中,进程在完成执行并退出后会通知其父进程。然后,父流程将从流程表中删除该流程。在此步骤中,如果父进程无法从其子进程(已完成的进程)中读取进程状态,则它将无法从内存中删除该进程,因此进程表中仍然存在已死的进程–因此,被称为僵尸进程!

查找Linux的僵尸进程

为了杀死僵尸进程,我们需要首先对其进行识别。以下命令可用于查找僵尸进程:
ps aux | egrep “Z|defunct”
输出的STAT列中的Z和/或最后一个(COMMAND)列中的[defunct]将标识Zombie进程。

Kill掉Linux的僵尸进程

僵尸进程是无法杀死的,因为它已经死了!所以想杀死僵尸进程,必须先显式地通知其父进程,以便它可以重试以读取子(死)进程的状态,并最终从进程表中清除它们。这可以通过向父进程发送SIGCHLD信号来完成。以下命令可用于查找父进程ID(PID):
ps -o ppid=
获得僵尸的父进程ID后,可以使用以下命令将SIGCHLD信号发送到父进程:
kill -s SIGCHLD
但是,如果这无助于清理Zombie进程,则您将不得不终止或重新启动其父进程,或者如果Zombie进程激增导致或走向系统中断,那么您将别无选择系统重启。以下命令可用于终止其父进程:
kill -9
请注意,杀死父进程将影响其所有子进程,因此快速进行仔细检查将有助于确保安全。另外,如果很少有僵尸进程不占用大量CPU /内存,则最好在下一次计划的系统维护中杀死父进程或重新启动系统。
昨天服务器到期,之前的服务器由于空间小,不能满足现在的服务要求,就新购买了一个服务器,目前正在调试安装中!
在调试过程中,发现系统中有很多僵尸进程,现在就是找出这些僵尸进程,并将其杀死。
用top查看系统中的僵尸进程情况
再看看这些僵尸是什么程序来的
ps -A -o stat,ppid,pid,cmd | grep -e ‘^[Zz]’
因为状态为 z或者Z 的进程为僵尸进程,所以我们使用grep抓取stat状态为zZ进程
运行结果参考如下

这里一共出现了6个僵死进程,我们需要把它们一个个都干掉,执行下面的命令
kill -9 16092
这样处理的速度有点慢,直接来个快速干掉所有僵尸进程的命令
ps -A -o stat,ppid,pid,cmd | grep -e ‘^[Zz]’ | awk ‘{print $2}’ | xargs sudo kill -9
再查看,僵尸进程没有了!

ps

(英文全拼:process status)命令用于显示当前进程的状态,类似于 windows 的任务管理器。
语法
ps [options] [—help]
参数

  • ps 的参数非常多, 在此仅列出几个常用的参数并大略介绍含义
  • -A 列出所有的进程
  • -w 显示加宽可以显示较多的资讯
  • -au 显示较详细的资讯
  • -aux 显示所有包含其他使用者的行程
  • au(x) 输出格式 :USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
    • USER: 行程拥有者
    • PID: pid
    • %CPU: 占用的 CPU 使用率
    • %MEM: 占用的记忆体使用率
    • VSZ: 占用的虚拟记忆体大小
    • RSS: 占用的记忆体大小
    • TTY: 终端的次要装置号码 (minor device number of tty)
    • STAT: 该行程的状态:
      • D (TASK_UNINTERRUPTIBLE) 不可中断的睡眠状态 (通常 IO 的进程)
      • R (TASK_RUNNING) 正在运行,或在队列中的进程
      • S (TASK_INTERRUPTIBLE) 可中断的睡眠状态
      • T (TASK_STOPPED) 停止状态
      • t (TASK_TRACED) 被跟踪状态
      • Z (TASK_DEAD - EXIT_ZOMBIE) 退出状态,但没被父进程收尸,成为僵尸状态
      • W 进入内存交换(从内核2.6开始无效)
      • X (TASK_DEAD - EXIT_DEAD) 退出状态,进程即将被销毁
      • < 高优先级
      • N 低优先级
      • L 有些页被锁进内存
      • s 包含子进程
        • 位于后台的进程组;
      • l 多线程,克隆线程 multi-threaded (using CLONE_THREAD, like NPTL pthreads do)
    • START: 行程开始时间
    • TIME: 执行的时间
    • COMMAND:所执行的指令

      一、后台进程管理命令

      fg、bg、jobs、&、ctrl + z、ctrl + c、ctrl + \、ctrl + d
      1、 &
      加在一个命令的最后,可以把这个命令放到后台执行 ,如gftp &,
      2、ctrl + z
      可以将一个正在前台执行的命令放到后台,并且处于暂停状态,不可执行
      3、jobs
      查看当前有多少在后台运行的命令
      jobs -l选项可显示所有任务的PID,jobs的状态可以是running, stopped, Terminated,但是如果任务被终止了(kill),shell 从当前的shell环境已知的列表中删除任务的进程标识;也就是说,jobs命令显示的是当前shell环境中所起的后台正在运行或者被挂起的任务信息;
      4、fg
      将后台中的命令调至前台继续运行
      如果后台中有多个命令,可以用 fg %jobnumber将选中的命令调出,%jobnumber是通过jobs命令查到的后台正在执行的命令的序号(不是pid)
      5、bg
      将一个在后台暂停的命令,变成继续执行 (在后台执行)
      如果后台中有多个命令,可以用bg %jobnumber将选中的命令调出,%jobnumber是通过jobs命令查到的后台正在执行的命令的序号(不是pid)
      将任务转移到后台运行:
      先ctrl + z;再bg,这样进程就被移到后台运行,终端还能继续接受命令。
      概念:当前任务
      如果后台的任务号有2个,[1],[2];如果当第一个后台任务顺利执行完毕,第二个后台任务还在执行中时,当前任务便会自动变成后台任务号码“[2]” 的后台任务。所以可以得出一点,即当前任务是会变动的。当用户输入“fg”、“bg”和“stop”等命令时,如果不加任何引号,则所变动的均是当前任务

      二、进程的终止

      后台进程的终止:
      方法一:
      通过jobs命令查看job号(假设为num),然后执行kill %num
      方法二:
      通过ps命令查看job的进程号(PID,假设为pid),然后执行kill pid
      前台进程的终止:
      ctrl+c

      三、进程的挂起

      后台进程的挂起:
      在solaris中通过stop命令执行,通过jobs命令查看job号(假设为num),然后执行stop %num;
      在redhat中,不存在stop命令,可通过执行命令kill -stop PID,将进程挂起;
      当要重新执行当前被挂起的任务时,通过bg %num 即可将挂起的job的状态由stopped改为running,仍在后台执行;当需要改为在前台执行时,执行命令fg %num即可;
      前台进程的挂起:
      ctrl+Z;
      清除掉所有挂起的进程
      1. #查案进程编号
      2. jobs
      3. #1..n为进程编号
      4. kill -9 %{1..n}
      5. # 清除记录
      6. jobs -l

      四、kill的其他作用

      kill除了可以终止进程,还能给进程发送其它信号,使用kill -l 可以察看kill支持的信号。
      SIGTERM是不带参数时kill发送的信号,意思是要进程终止运行,但执行与否还得看进程是否支持。如果进程还没有终止,可以使用kill -SIGKILL pid,这是由内核来终止进程,进程不能监听这个信号。

      五、区别

      ctrl+z(挂起)、ctrl+c(中断)、ctrl+\(退出)和ctrl+d(EOF)的区别
      1、四种操作的表现
      ctrl+c强行中断当前程序的执行。
      ctrl+z将任务中断,但是此任务并没有结束,他仍然在进程中,只是放到后台并维持挂起的状态。如需其在后台继续运行,需用“bg 进程号”使其继续运行;再用”fg 进程号”可将后台进程前台化。
      ctrl+\表示退出。
      ctrl+d表示结束当前输入(即用户不再给当前程序发出指令),那么Linux通常将结束当前程序。
      2、ctrl+c,ctrl+d,ctrl+z在linux中意义。
      linux下:
      ctrl+c 发送 SIGINT 信号给前台进程组中的所有进程。常用于终止正在运行的程序。
      ctrl+z 发送 SIGTSTP 信号给前台进程组中的所有进程,常用于挂起一个进程。
      ctrl+d 不是发送信号,而是表示一个特殊的二进制值,表示 EOF。
      ctrl+\ 发送 SIGQUIT 信号给前台进程组中的所有进程,终止前台进程并生成 core 文件。
      Key Function
      Ctrl+c Kill foreground process
      Ctrl+z Suspend foreground process
      Ctrl+d Terminate input, or exit shell
      Ctrl+s Suspend output
      Ctrl+q Resume output
      Ctrl+o Discard output
      Ctrl+l Clear screen