首页 > 解决方案 > 父母在创建孩子后使用信号杀死 n 个孩子

问题描述

我正在尝试从父进程创建 n 个子进程,然后在创建 n 个子进程后,父进程必须使用信号一一杀死它们。

当父母杀死一个孩子时,父母必须等待 2 秒才能杀死下一个孩子。最后,当父母杀死所有孩子时,父母也必须完成。

创建时每个子进程都必须打印其进程 ID,直到父进程杀死它。我尝试结合从各种网站上阅读的内容,到目前为止,我能够创建孩子并打印他们的进程 ID,但我无法使用信号杀死他们。我怎么做?

这是代码:

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

void handle_sigint(int sig) { 
    signal(sig,handle_sigint);
    exit(0);
} 

int main(int argc, char *argv[]) {
    char *ptr=argv[1];
    int n=atoi(ptr);//number of processes to be created
    pid_t p[n];

    for(int i = 0; i < n; i++) {  
        signal(SIGINT, handle_sigint);    
        if ((p[i] = fork()) == 0) {
            while(1) 
                printf("%d %d\n",getpid(),i);                   
        } 
        sleep(2);                                
    }

    for (int i = 0; i < n; i++) {
        kill(p[i],SIGINT);
        sleep(2);
    }

    for (int i = 0; i < n; i++) {
        wait(NULL);
    }

    return 0;
}

标签: cunixsignalsfork

解决方案


首先,您不需要信号处理程序,因为有许多信号的默认操作是导致接收进程终止。实际上,SIGINT您已经在使用的就是其中之一,但SIGTERM对于该目的来说,这将是一个更合适的选择。我会通过摆脱处理程序及其注册来简化,我会让父发送SIGTERM而不是SIGINT.

但是,如果您确实保留了信号处理程序,那么您应该使用sigaction(),而不是signal()来注册它,并且您应该从处理程序实现中省略重新注册,因为正确使用sigaction()会使它变得不必要。此外,信号处理程序只允许调用异步信号安全函数,而exit()不是其中之一。您可以使用_exit()or_Exit()代替,但同样,完全删除处理程序会更简单。

尽管如此,我还是倾向于怀疑原始代码失败的原因是信号处理程序的签名不正确,您在编辑中对其进行了更正。处理程序调用 仍然是错误的exit(),但在实践中,由此产生的未定义行为的表现很可能包括程序终止。


推荐阅读