僵尸进程:Linux系统中的隐秘威胁|如何查看并清理僵尸进程

文章目录

在 Linux 系统中,僵尸进程(Zombie Process)是一种特殊的进程状态,虽然已经完成执行,但仍然保留在进程表中。本文将介绍僵尸进程的定义、危害、产生原因以及如何处理它们。

什么是僵尸进程?

僵尸进程是指已经完成执行(通过exit系统调用、运行时发生致命错误或收到终止信号所致),但在操作系统的进程表中仍然存在其进程控制块(PCB)的进程。

尽管这些进程不再执行任何实际任务,但它们占据了一个位置,直到父进程调用wait()waitpid()来获取其退出状态。

僵尸进程的危害

虽然僵尸进程不会占用 CPU 资源,但它们会占用系统内存和进程表中的位置,影响系统性能和稳定性。

如果系统中存在大量僵尸进程,可能导致进程表耗尽,从而无法创建新的进程。

僵尸进程产生的原因

1、父进程未回收子进程资源

当父进程先于子进程结束,子进程成为孤儿进程。

孤儿进程会被 init 进程(进程号为 1)领养,并由 init 进程对其完成状态收集工作。

如果子进程先于父进程退出,同时父进程太忙无法回收子进程的资源,子进程的 PCB 存放于内核中,变成僵尸进程。

2、模拟僵尸进程的产生

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(void) {
    pid_t pid = fork();
    if (pid == 0) {
        printf("I am child, my parent=%d, going to sleep 3s\n", getppid());
        sleep(3);
        printf("-------------child die--------------\n");
    } else if (pid > 0) {
        printf("I am parent, pid=%d, my son=%d, going to sleep 5s\n", getpid(), pid);
        sleep(5);
        system("ps -o pid,ppid,state,tty,command");
    } else {
        perror("fork");
        return 1;
    }
    return 0;
}

在这个程序中,父进程创建子进程后休眠 5 秒钟,子进程休眠 3 秒钟后退出。

如果父进程在子进程退出之前结束,子进程成为僵尸进程。

如何查看僵尸进程

用 ps 命令和 grep 命令查看僵尸进程:

ps -A -ostat,ppid,pid,command | grep -e '^[Zz]'

命令注解:

  • -A:列出所有进程
  • -o: 自定义输出字段,设定显示字段为 stat(状态),ppid(父进程 pid),pid(进程 pid),command(命令行)这四个参数
  • 因为状态为 Z 或者 z 的进程为僵尸进程,所以我们使用 grep 抓取 stat 状态为 Zz 进程

运行结果如下所示:

Z 829377 829380 /command

如何杀死僵尸进程

对于普通进程,我们可以使用kill命令来终止它们。

但对于僵尸进程,因为它们已经“死”过一次,无法再利用kill命令杀死。

解决方法是杀死父进程,init 进程会领养僵尸进程并回收其资源。

例如,如果 PID 829380 是一个僵尸进程,其父进程是 PID 829377,可以使用kill结束父进程(829377)来清理僵尸进程:kill -HUP 829377

总结

  1. 僵尸进程是 Linux 系统中的隐秘威胁,需要及时处理,以保持系统的健康运行。
  2. 父进程应该负责回收子进程的资源,避免产生僵尸进程。
  3. 使用合适的命令或方法来清理僵尸进程。

也可以看看