如何保证多个孩子的信号传递

时间:2010-09-02 22:20:43

标签: concurrency synchronization ipc signals parent-child

作为Linux基准测试应用程序的一部分,我有一个父进程,它会分叉多个子进程并行执行任务。我正在使用信号来协调它们,因为我正在寻找尽可能精确的时序。每个孩子都将为测试做准备,然后通过信号输入由父母控制的“屏障”。

一旦所有孩子都进入了障碍,父母就会记录时间戳,并指示子进程开始。一旦孩子完成测试的每个部分,他们就会在进入下一个障碍之前向父母发出信号。父节点正在侦听这些信号,一旦从所有子进程接收到它们,它就会记录完成时间。

我的问题是程序以非确定性方式终止;信号并不总是得到传递。信号处理程序不能更简单:

void sig_child_ready (int sig)
{
    num_child_ready++;
}

num_child_ready被声明为volatile sig_atomic_t。我尝试在这样的循环中使用sigprocmask但没有成功:

sigprocmask (SIG_BLOCK, &mask, &oldmask);
while (num_child_ready < num_child)
{
    /* waiting for child signals here */
    sigsuspend (&oldmask);
}
sigprocmask (SIG_UNBLOCK, &mask, NULL);

我不确定如何从这里开始。我是否正确需要sigprocmask来“排队”信号,以便逐个处理它们?

或者,考虑这个假设情景:父母接收信号,正在执行其处理程序,然后接收另一个相同的信号。信号处理程序是递归调用的吗?即它会在返回并完成第一个处理程序之前执行第二个处理程序吗?

我只是想确保所有信号尽可能同步传送。

1 个答案:

答案 0 :(得分:3)

正常信号没有排队,这可能是导致问题的原因。

如果在处理程序运行过去的信号之前有一个信号到达,它们将被合并,你几乎无法做到这一点 - 你可能最好使用其他形式的IPC来做这种同步

您可以使用“实时信号”,它们会排队等候。您将使用sigqueue()和发送信号 使用sigwaitinfo()“接收”它们或建立信号处理程序,在struct sigaction

中设置SA_SIGINFO标志