在对多个文件描述符使用轮询的同时,如何捕获子进程的所有信号?

问题描述

所以我有这个任务,他们告诉我必须创建一个流程树(使用 number_of_children 分叉),将一些消息从底层工作人员发送到流程树的根,最后工人退出后,他们必须向root发送SIGUSR1信号。经过一些(与我的问题无关)打印之后,必须打印接收到的信号数量

首先,我设置信号处理程序,调用此例程(我在网上找到它,并且我认为它工作得很好):

void set_signal_handler(int signo,void (*handler)(int,siginfo_t *,void *)) {
    struct sigaction act;
    memset(&act,'\0',sizeof(act));
    act.sa_sigaction = handler;
    act.sa_flags = SA_SIGINFO;
    // set up signal handler 
    if (sigaction(signo,&act,NULL) < 0) {
        perror ("sigaction");
        exit(1);
    }
}

然后,我使用for循环为每个子代创建一个未命名的管道数组,然后派生这些子代,最后调用一个监视文件描述符的例程,以便我可以非阻塞方式进行读取。轮询的逻辑如下:

while(open_files>0) {
    int retval = poll(fds,number_of_children,0);

    // try to read only if poll does not fail
    if (retval > 0) {
        for(int i = 0; i < number_of_children; i++){
            reading from children
        }
    }
}

通过这种方式,我读取了所有写入内容(尽管轮询有时会被信号打断),并且读取没有问题。

实际问题是,当我打印SIGUSR1信号接收到根时,我没有得到一致的值。假设在每个进程节点的3个子进程中,我得到的值从3到9(正确)。有没有更安全的方法来处理信号而不愚蠢。

注意:经过一些研究,我知道我无法让相同类型的信号挂起(我尝试使用sigqueue发送信号)。我还尝试忽略轮询期间的信号,并在轮询结束时重新设置处理程序,但是,由于信号已哑,因此它当然不起作用。我还签出了一个相对的堆栈文章,并声明我的signal_counter为volatile sig_atomic_t,但仍然不一致。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)