c - 等子孙

标签 c unix signals

如何在不阻塞信号处理程序的情况下等到所有子孙子都退出?这是我目前的尝试。

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

int run = 1;

void handler(int sig, siginfo_t *info, void *uap)
{
    int exit_code;

    printf("sigchld pid %d\n", info->si_pid);
    pid_t pid = waitpid(-1, &exit_code, 0);
    if (pid == -1) {
        perror("waitpid()\n");
    } else {
        printf("waitpid returned %d\n", pid);
    }
    // set run = 0 when all children exit

    printf("end of sigchild handler\n");
}

void main() {

    struct sigaction chld;
    chld.sa_sigaction = handler;
    chld.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
    sigaction(SIGCHLD, &chld, NULL);

    //procmask sigchld?
    if (!fork ()) {
        if (!fork ()) {
            sleep(2);
            printf ("grand-son exit: %d\n", getpid());
            exit (0);
        }
        sleep(1);
        printf ("son exit: %d\n", getpid());
        exit (0);
    }

    while(run)
        sleep(1);

    printf("ciao\n");
}

最佳答案

虽然 SIGCHLD 和 waitpid 等确实只适用于直系子级,但在 UNIX 系统上,您通常可以通过从父级传递给子级到孙级的继承资源来“作弊” , 并在进程终止时关闭。

例如,原始进程可能会打开一个 pipe ,并可能设置它的read结尾close-on-exec ,让子孙继承写端。当原始进程准备好等待所有后代终止时,它会关闭管道的写入端并阻塞readselect 以提高剩余描述符的可读性。当最后一个后代终止时,管道的读取端将传递一个 EOF。

这种策略并不能保证——子孙可能会谨慎地关闭继承的文件描述符——但它通常很有效。

关于c - 等子孙,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8391938/

相关文章:

linux - 如何解决 UNIX 中的 Not a Directory 错误消息

shell - 根据公共(public)字段将多行变成一行(分组依据)

c++ - 错误 : implicit declaration of function `int open(...)'

linux - 哪些系统调用不会被信号中断?

java - 从 java 调用脚本,收到 sigpipe 信号

C 代码,简单的 Web 服务器(代码 OK)

c++ - 用大括号初始化 VLA 是 GCC 错误还是扩展?

c - 基于ncurses的程序拦截SIGWINCH后无法识别按键

c - 如何修复C中无法访问的代码?我无法打印用户的输入

c - 如何在 C 中根据用户输入进行十字符号