📜  僵尸进程及其预防(1)

📅  最后修改于: 2023-12-03 15:07:02.815000             🧑  作者: Mango

僵尸进程及其预防

什么是僵尸进程?

在Unix/Linux操作系统中,当一个进程结束运行后,它会留下一个进程描述符,但是它的父进程没有调用wait或者waitpid来读取它的退出状态码信息。这样的进程称为僵尸进程。

僵尸进程会占用系统资源,而且如果系统中因为产生过多的僵尸进程而导致进程数量达到上限时,新的进程将无法创建,从而导致系统宕机。

如何预防僵尸进程?
  1. 使用wait或waitpid回收子进程资源

使用wait或waitpid可以防止僵尸进程的产生,因为父进程必须要等待子进程结束并取回状态码之后,才能真正地终止子进程。(示例代码如下:)

#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int main()
{
    pid_t pid;
    int status;

    if ((pid = fork()) < 0) {
        printf("fork error\n");
        exit(1);
    } else if (pid == 0) {   // child process
        // do something
    } else {   // parent process
        wait(&status);
    }
    return 0;
}
  1. 使用信号处理器处理SIGCHLD信号

父进程可以注册SIGCHLD信号处理器,捕获子进程退出信号。在信号处理器中可以调用wait或waitpid来回收子进程资源。(示例代码如下:)

#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

void sigchld_handler(int sig)
{
    pid_t pid;
    int status;

    while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
        printf("child process %d terminated\n", pid);
    }
}

int main()
{
    pid_t pid;

    if ((pid = fork()) < 0) {
        printf("fork error\n");
        exit(1);
    } else if (pid == 0) {   // child process
        // do something
    } else {   // parent process
        signal(SIGCHLD, sigchld_handler);
    }
    return 0;
}
总结

预防僵尸进程的方法主要有两种:一种是在父进程中使用wait或waitpid来回收子进程资源,另一种是在父进程中注册SIGCHLD信号处理器,捕获子进程退出信号,在信号处理器中调用wait或waitpid来回收子进程资源。