僵尸进程是什么?2025年4月28日 | 阅读 8 分钟 僵尸进程或废弃进程是指一个进程已经完成执行(通过exit系统调用),但其在进程表中的条目仍然存在。这种情况发生在子进程中,因为父进程需要该条目来读取子进程的退出状态。一旦通过wait系统调用读取了退出状态,僵尸进程的条目就会从进程表中移除,这个过程称为“收割”。子进程在从资源表中移除之前,总是会先变成僵尸进程。 在大多数情况下,僵尸进程会立即被其父进程等待,然后在正常的系统运行中被系统收割。长时间保持僵尸状态的进程通常是错误的,会导致资源泄露,但它们只占用进程表中的一个条目。 从术语的比喻来看,子进程已经死亡,但尚未被收割。此外,与普通进程不同,kill命令不会影响僵尸进程。 ![]() 不应将僵尸进程与孤儿进程混淆。孤儿进程是指一个进程仍在执行,但其父进程已死亡。当父进程死亡时,孤儿子进程将被init(进程ID为1)收养。孤儿进程死亡时,不会保留为僵尸进程;相反,它们会被init等待。因此,一个既是僵尸进程又是孤儿进程的进程将被自动收割。 僵尸进程如何工作?在操作系统中,僵尸进程的工作方式如下:
示例我们来看一个僵尸进程的例子。 输出:它会给出如下输出,例如 parent9 Child3 Child4 Child2 Child5 Child1 Child6 Child0 Child7 Child8 Child9 // there is a pause here parent8 parent7 parent6 parent5 parent4 parent3 parent2 parent1 parent0 在第一个循环中,原始(父)进程分叉了10个自身的副本。每个子进程都会打印一条消息,然后休眠并退出。由于父进程在循环中做的很少,所以所有子进程几乎同时创建,因此它们第一次被调度的时间有些随机,导致它们的输出消息顺序混乱。 在循环期间,会构建一个子进程ID数组。所有11个进程都有pids[]数组的副本,但只有在父进程中它是完整的。每个子进程中的副本将缺少较低编号的子进程PID,并且其自身的PID为零。 第二个循环仅在父进程中执行,并等待每个子进程退出。它会等待休眠10秒的子进程,而其他子进程早已退出,因此除了第一条消息之外,所有消息都会很快显示。这里没有随机排序的可能性,因为它是单个进程中的一个循环驱动的。父进程可能会在任何子进程开始执行之前就进入第二个循环。这再次是进程调度器的随机行为——“parent9”消息可能出现在“parent8”之前序列中的任何位置。 Child0到Child8在它们退出和父进程对它们执行waitpid()之间,会花费一秒或更长的时间处于这个状态。父进程在Child9退出之前就已经在等待它,所以那个进程几乎没有时间作为僵尸进程。 僵尸进程的危险僵尸进程不使用任何系统资源,但它们会保留其进程ID。如果有很多僵尸进程,那么所有可用的进程ID都会被它们垄断。这会阻止其他进程运行,因为没有可用的进程ID。 如果僵尸进程的父进程已不再运行,则僵尸进程通常表明操作系统存在bug。如果只有少数僵尸进程,这不是一个严重的问题,但在更重的负载下可能会给系统带来问题。 预防僵尸进程的方法我们需要防止创建僵尸进程,因为每个系统只有一个进程表,并且进程表的大小是有限的。如果生成了过多的僵尸进程,那么进程表就会被填满。系统将不会生成任何新进程,然后系统将陷入停顿。因此,我们需要防止僵尸进程的创建。以下是防止僵尸进程创建的不同方法,例如: ![]() 1. 使用wait()系统调用 当父进程在创建子进程后调用wait()时,它将等待子进程完成并获取其退出状态。父进程将被挂起(在等待队列中等待),直到子进程终止。必须理解的是,在此期间,父进程不做任何事情,只是等待。 2. 通过忽略SIGCHLD信号 当子进程终止时,会向父进程发送一个相应的SIGCHLD信号。如果我们调用“signal(SIGCHLD,SIG_IGN)”,系统就会忽略SIGCHLD信号,并且子进程的条目会从进程表中删除。这样就不会创建僵尸进程。然而,在这种情况下,父进程无法得知子进程的退出状态。 3. 使用信号处理器 父进程为SIGCHLD信号安装一个信号处理器。信号处理器在其内部调用wait()系统调用。在这种情况下,当子进程终止时,SIGCHLD信号将被传递给父进程。收到SIGCHLD后,相应的处理器将被激活,它会调用wait()系统调用。因此,父进程立即收集退出状态,并且子进程在进程表中的条目会被清除。这样就不会创建僵尸进程。 如何终止僵尸进程?可以通过使用kill命令向父进程发送SIGCHLD信号来终止僵尸进程。该信号会通知父进程使用wait()系统调用清理僵尸进程。该信号使用kill命令发送。演示如下: 在上面的命令中,pid是父进程的进程ID。 什么是SIGHLD信号?SIGCHLD是UNIX和类UNIX系统的信号。siginfo_t的代码值如下:
|
我们请求您订阅我们的新闻通讯以获取最新更新。