您如何在 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 多处理中等待恰好两个信号?的主要内容,如果未能解决你的问题,请参考以下文章