簡體   English   中英

為什么這個程序會創建一個僵屍進程,我該如何解決?

[英]why does this program create a zombie process and how do I fix it?

我的問題是我無法承認為什么這些代碼仍會生成僵屍進程。 我怎么修好它? 謝謝。

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


int count = 0;

/**
 * signal  callback
 * @param signo
 */
void sigcallback(int signo) {
    short stime = 5;
    int status;
    wait(&status);
    while (1) {

        printf("wake up,%d\n", getpid());
        sleep((stime + 1) - (short) (time(NULL) % stime));

    }
}

int call_cmd(void) {
    count++;

    int i;
    pid_t pid;
    signal(SIGCHLD, sigcallback);
    for (i = 0; i < 3; i++) {
        if ((pid = fork()) < 0) {
            printf("error with fork\n");
            exit(1);
        } else if (pid > 0) {
            waitpid(pid, NULL, WNOHANG);
        } else {
            printf("\t\t\tsid is %d,count is %d,pid is %d\n", getsid(getpid()), count, getpid());
        }
    }
    return 1;
}

void notice_root(int signo) {
    printf("execut root signal\n");
    waitpid(0, NULL, 0);
}

int main(void) {
    pid_t pid;

    int i;
    signal(SIGCHLD, notice_root);
    for (i = 0; i < 2; i++) {
        if ((pid = fork()) < 0) {
            printf("error with fork\n");
            exit(1);
        } else if (pid > 0) {
            exit(0);
        } else {
            setsid();
            call_cmd();
        }
    }
    return 0;
}

您的信號處理程序sigcallback有一個無限的睡眠循環。 一旦該函數處理了一個信號,該進程將永遠不再處理另一個SIGCHLD信號,因為信號處理程序永遠不會返回。 這可能是你的僵屍的原因。

您沒有為每個退出的孩子提供一個信號。 如果兩個孩子“同時”退出,您只能獲得一個SIGCHLD 因此,當您在信號處理程序(其中任何一個)中等待時,您應該在循環中等待所有已退出的子項。 有點像:

for (;;) {
    pid_t p = waitpid(-1, 0, WNOHANG);
    if (p <= 0) break;
    /* ... */
}

當您的進程退出時,該進程的子進程將由init進程繼承,因此它們將被正確地獲取。 然而,你的無限循環阻止了三件事:

  • 它不會同時收獲退出的孩子。
  • 在收獲第一個孩子后,它不會再收獲任何孩子了。
  • 它不允許進程退出,因此init進程無法獲得子進程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM