您如何在 C 多处理中等待恰好两个信号?

Posted

技术标签:

【中文标题】您如何在 C 多处理中等待恰好两个信号?【英文标题】:How do you wait for exactly two signals in C multiprocessing? 【发布时间】:2021-03-17 17:34:56 【问题描述】:

在主函数中,我创建了一个连接到 handler 的“sigaction sigact”,并从阻塞中删除了 SIGUSR1 信号sigact.sa_mask 集。 SIGUSR1 是我想从两个孩子那里得到两次的信号,然后再进一步。如何等待两个子进程从中获取 SIGUSR1 信号?

void handler(...)...

int main()

    int pipe1[2];
    int pipe2[2];
    
    char buf;

    struct sigaction sigact;
    sigact.sa_handler = handler;
    sigfillset(&sigact.sa_mask);
    sigact.sa_flags = 0;
    sigdelset(&sigact.sa_mask,SIGUSR1);
    sigaction(SIGUSR1,&sigact,NULL);

    pid = fork();

    if(pid == 0)
       
       ...
       sleep(3);                                     // the sleep is just a must-have of the homework
       kill(getppid(),SIGUSR1);                      // CHILD1
       ...                         

    else
          pid1 = fork();

          if(pid1 == 0)

                ...
                sleep(3);
                kill(getppid(),SIGUSR1);             // CHILD2
                ...               
         
          else

               ...
               sigsuspend(&sigact.sa_mask);                    // PARENT
               sigsuspend(&sigact.sa_mask);                    // WAIT FOR SIGUSR1 FROM CHILD1 AND
               ...                                             // CHILD2 BEFORE GOING FURTHER
               ...                                             // (The two sigsuspends were my best idea, 
               ...                                             //  doesn't work)
               // DO OTHER THINGS AFTER TWO SIGNALS CAME 
               // (e.g. sending children data with pipes, 
               // just homework stuff...)

          
    
    return 0;

如您所见,我正在尝试使用两个 sigsuspend,但它们不起作用,它会永远等待。仅使用一个 sigsuspend 即可,但我需要两个孩子的反馈。

如何等待 2 个信号?

【问题讨论】:

我认为没有办法做到这一点。考虑使用管道从孩子那里接收。 我不能,因为那是大学 xD 的作业,但谢谢@Joshua 要允许 SIGUSR1 中断已经运行的 SIGUSR1 处理程序,您必须从处理程序的sa.sa_mask 中清除 SIGUSR1(就像您所做的那样)还有set the SA_NODEFER flag。 作为Linux man pages notes,sigsuspend 通常与sigprocmask 结合使用,以暂时取消屏蔽其他被阻塞的信号。想象一下,您在子级中没有sleep(3),但仍希望父级在调用sigsuspend被打断。 【参考方案1】:

在您的限制条件下,这无法可靠地完成。推迟这项作业。

如果两个 SIGUSR1 信号“同时”到达,一个会丢失,因为ordinary UNIX signals of the same type do not queue。你不能控制这个时间——操作系统调度程序可以。

所以,做点别的吧。使用可以queue at least 32 (_POSIX_SIGQUEUE_MAX) pending signals的实时信号。在孩子和父母之间使用管道进行交流。每个进程使用不同的普通信号(例如,SIGUSR1 和 SIGUSR2)。等等。

【讨论】:

以上是关于您如何在 C 多处理中等待恰好两个信号?的主要内容,如果未能解决你的问题,请参考以下文章

C多线程编程信号处理

您如何等待主队列完成处理程序?

MFC中如何让多线程按先后顺序执行,第一个来的先执行,以后按先后到达的顺序执行

每 20 秒打印一次消息的信号(C 多线程程序)

您如何等待任务计划程序任务在批处理文件或 C# 中完成?

如何中止对 sigwaitinfo 的调用?