C 等待孩子和孙子

C 等待孩子和孙子,c,unix,signals,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 *inf

你怎么能等到所有的孩子和孙子都退出,而不阻塞信号处理器?这是我迄今为止的尝试

#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系统上,您通常可以通过将继承的资源从父代传递到子代,再传递到孙代,并在进程终止时关闭来进行一些欺骗

例如,原始进程可能会打开一个,并且可能会设置它的读取端,以便子进程和子进程继承写入端。当原始进程准备等待所有子进程终止时,它将关闭管道的写入端,并对剩余描述符进行块读取或选择可读性。当最后一个子体终止时,管道的读取端将传递一个EOF


这种策略不能保证——孩子或孙子可能会谨慎地关闭继承的文件描述符——但它通常工作得很好。

你不能等待孙子;如果一个子进程退出时没有等待它自己的子进程,那么这些子进程通常会被重新分配到根进程或初始化进程。请参阅1 main returns int.2不要在信号处理程序中使用printf。3两次分叉是孙辈从祖辈进程分离的一种方式,但是从终端组分离可能需要一些额外的系统调用