UNIX信号处理。在SIGCHLD处理程序中等待。C

Иго*_*нко 2 c unix signals wait sigchld

我有一个父母和一个孩子的过程。在父级中,我为SIGCHLD建立了信号处理程序。我将SIGTSTP信号发送给子级,该子级触发SIGCHLD并在父级的SIGCHLD siganl处理程序中调用调用函数以获取已停止子级的状态。但它不会立即返回,而是会阻塞。然后,我向孩子发送SIGCONT信号,并等待errno设置为Interuppted系统调用。我不明白我在想什么。

pid_t pid;


static void sig_chld(int signo);


int main() {

    struct sigaction act, savechld;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;


    act.sa_handler = sig_chld;
    if (sigaction(SIGCHLD, &act, &savechld) < 0){
        return errno;
    }

    pid = fork();
    switch (pid){
        case -1:{
            perror("fork failed");
            return errno;
        }
        case 0:{    //child
            if (sigaction(SIGCHLD, &savechld, NULL) < 0)
                return errno;

            execlp(path, name_of_executable, (char*)NULL);
            return errno;
        }
        default:{
            for (;;)
                pause();
        }
    }
    return 0;
}



void sig_chld(int signo) {
    int statol;
    if (wait(&statol) < 0){
        perror("waitt error");
        exit(errno);
    }

    if (WIFSTOPPED(statol)){
        puts("Child is stopped");
    } else if (WIFEXITED(statol)){
        puts("Child exited");
    } else if (WIFCONTINUED(statol)){
        puts("Child continued");
    } else if (WIFSIGNALED(statol)){
        puts("Child is signaled");
        int sig = WTERMSIG(statol);
        psignal(sig, NULL);
    }
}
Run Code Online (Sandbox Code Playgroud)

Ctx*_*Ctx 5

您必须使用waitpid()代替wait(),并且需要指定选项WUNTRACED来也停止报告的子项waitpid(),如下所示:

if (waitpid(-1, &statol, WUNTRACED) < 0) {
Run Code Online (Sandbox Code Playgroud)

现在waitpid()应该立即返回,并且您的宏WIFSTOPPED(&statol)应该为true。

  • 您可能也可以使用`WNOHANG`,尽管不循环也没关系。但是,一个进程可以有多个子级(甚至是当前程序未启动但执行当前程序的程序也没有等待的程序的子级),并且您可能需要收集多个尸体。 (2认同)