【问题标题】:Boost Semaphores under linux and EINTR return codelinux下Boost Semaphores和EINTR返回码
【发布时间】:2015-04-06 08:48:23
【问题描述】:

在 boost(我使用 1.54.0)中,我看到了 posix 信号等待的实现:

inline void semaphore_wait(sem_t *handle)
{
   int ret = sem_wait(handle);
   if(ret != 0){
      throw interprocess_exception(system_error_code());
   }
}

posix 信号量手册说:

错误

  EINTR  The call was interrupted by a signal handler; see signal(7).

如果我将 kill 发送到等待线程,我对提升信号量抛出异常是否正确?如果是这样,您如何处理这种情况?

【问题讨论】:

  • 除非线程被设计为处理它,否则不要向线程发送终止。
  • @DavidSchwartz 在一般情况下,我无法确定它是否为它设计。当您在连接中发送获得 RST 的东西时,我也可以获得类似 SIGPIPE 的东西,这对于 TCP 应用程序很常见。
  • 如果您不知道线程将如何处理信号,您为什么要将该信号发送给线程?!向线程发送信号的唯一原因是因为您知道该线程在收到该信号时要做什么,并且您希望它这样做。线程必须合作。
  • @DavidSchwartz 好的,哪个线程处理进程范围的信号 SIGHUP 或 SIGTERM?据我了解,任何不掩盖它的东西。
  • 没错。进程不希望处理这些信号的线程应该屏蔽它们。进程确实希望处理这些信号的线程不应该。如何处理进程范围的信号是一个进程级别的实现决策。

标签: c++ linux boost synchronization semaphore


【解决方案1】:

在我看来,这可能是 Boost.Interprocess 中的一个错误。请向开发人员报告,如果这是故意的,他们至少能够提供理由。

评论上述 cmets 中的信号管理建议。确实,典型的多线程应用程序应该屏蔽掉不打算由线程处理的信号,只留下一个线程来处理信号。但是,这不是强制性规则。

首先,辅助线程可以由内部不处理信号的库产生,将其留给应用程序。信号处理程序可能会在这些线程中被调用。

其次,某些信号可能会被故意不屏蔽以捕获与该特定线程相关的事件。例如,可以为 SIGSEGV 注册一个处理程序以检测分段错误。这个处理程序将在有问题的线程中被调用,并且应用程序理论上可以处理该错误。同样,SIGUSR1 或 SIGUSR2 可用于向特定线程发送应用程序定义的事件。

底线是,即使设计良好的应用程序应该将信号处理提取到单独的线程中,库也不应该假设并准备好它不会。在任何情况下,在 EINTR 情况下抛出看起来都不是正确的行为。

【讨论】:

【解决方案2】:

实现看起来不错。可以使用 SA_RESTART 标志,以便自动重新启动呼叫。 http://man7.org/linux/man-pages/man7/signal.7.html

【讨论】:

    猜你喜欢
    • 2017-12-20
    • 1970-01-01
    • 1970-01-01
    • 2015-09-02
    • 2012-08-04
    • 2013-04-02
    • 1970-01-01
    • 1970-01-01
    • 2019-01-10
    相关资源
    最近更新 更多