你怎么用wait()杀死僵尸进程

mud*_*omp 4 c linux virtualbox zombie-process wait

我有这个代码,需要父母分叉3个孩子.

  • 你怎么知道(和)把"wait()"语句放在哪里来杀死
    僵尸进程?

  • 如果你有Linux虚拟盒,那么查看僵尸进程的命令是什么?

    main(){
    
     pid_t child;
     printf("-----------------------------------\n");
     about("Parent");
     printf("Now ..  Forking !!\n");
     child = fork();
     int i=0;
    
     for (i=0; i<3; i++){
        if (child < 0) {
            perror ("Unable to fork");
            break;
        } 
        else if (child == 0){
            printf ("creating child #%d\n", (i+1));
            about ("Child");
            break;
        }
    
        else{
            child = fork();
        }
      } 
    }       
    
    void about(char * msg){
    
     pid_t me;
     pid_t oldone;
    
     me = getpid();
     oldone = getppid();
    
     printf("***[%s] PID = %d   PPID = %d.\n", msg, me, oldone);
    
    }
    
    Run Code Online (Sandbox Code Playgroud)

Joh*_*ger 9

你怎么知道(和)把"wait()"语句放在哪里来杀死僵尸进程?

如果你的父母只产生一小部分固定数量的孩子; 不关心他们何时或是否停止,恢复或完成; 并且它本身很快退出,然后您不需要使用wait()waitpid()清理子进程.init进程(pid 1)负责处理孤立的子进程,并在完成后对其进行清理.

但是,在任何其他情况下,您必须wait()进行子进程.这样做可以释放资源,确保孩子已经完成,并允许您获得孩子的退出状态.通过waitpid()当一个孩子被停止或恢复用的信号,如果你愿意的话,你也可以收到通知.

至于在哪里进行等待,

  • 您必须确保只有父母 wait() s.
  • 您应该在您需要孩子完成(但不是在分叉之前)的最早点之前或之前等待,或者
  • 如果您不关心孩子何时或是否完成,但您需要清理资源,那么您可以定期打电话waitpid(-1, NULL, WNOHANG)收集一个僵尸孩子(如果有的话),如果没有则不会阻塞.

特别是,您不能 wait()(无条件地)在fork()ing 之后立即执行,因为父级和子级运行相同的代码.您必须使用返回值fork()来确定您是在子级(返回值== 0)还是在父级(任何其他返回值)中.此外,父母必须wait()只有在分叉成功的情况下,在这种情况下才fork()返回孩子的pid,它总是大于零.返回值小于零表示无法fork.

你的程序并不真正需要,wait()因为它会产生四个(而不是三个)孩子,然后退出.但是,如果您希望父母在任何时候最多只有一个活孩子,那么您可以这样写:

int main() {
    pid_t child;
    int i;

    printf("-----------------------------------\n");
    about("Parent");

    for (i = 0; i < 3; i++) {
        printf("Now ..  Forking !!\n");
        child = fork();

        if (child < 0) {
            perror ("Unable to fork");
            break;
        } else if (child == 0) {
            printf ("In child #%d\n", (i+1));
            about ("Child");
            break;
        } else {
            /* in parent */
            if (waitpid(child, NULL, 0) < 0) {
                perror("Failed to collect child process");
                break;
            }
        }
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果父节点在其一个或多个子节点之前退出,如果它不等待就会发生,那么子节点此后将看到其父进程为pid 1.

其他人已经回答了如何通过ps命令获取僵尸进程列表.你也可以通过看僵尸top.使用原始代码,你不太可能看到僵尸的一瞥,因为父进程很快退出,然后init将清理它留下的僵尸.