【问题标题】:How to guarantee signal delivery from multiple children如何保证来自多个孩子的信号传递
【发布时间】:2023-03-08 21:19:01
【问题描述】:

作为 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 来“排队”信号以便一一处理?

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

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

【问题讨论】:

    标签: concurrency synchronization ipc signals parent-child


    【解决方案1】:

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

    如果一个信号在处理程序为过去的信号运行之前到达,它们将被合并,您对此无能为力 - 您最好使用其他形式的 IPC 来执行这种同步.

    您可以使用“实时信号”,它会排队。您将使用 sigqueue() 发送信号和 使用sigwaitinfo() “接收”它们或建立一个信号处理程序,在struct sigaction 中设置 SA_SIGINFO 标志

    【讨论】:

    • 终于让它工作了......使用 sigqueue() 发送给多个孩子还有另一个问题。我假设我可以使用它来发送给所有孩子,因为我可以使用 kill: kill (0, SIGUSR1) 似乎这不能用 sigqueue() 完成!这个页面非常有用:davmac.org/davpage/linux/rtsignals.html
    猜你喜欢
    • 2013-03-29
    • 1970-01-01
    • 2015-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-22
    • 1970-01-01
    相关资源
    最近更新 更多