sigtimedwait() 的跨 (POSIX) 平台模拟

Cross (POSIX) platform analog for sigtimedwait()

用例是需要在自己执行 write() and/or SSL_write() 的 pthreads 中屏蔽 SIGPIPE 并让它在当前 POSIX- 上编译Linux、macOS、BSD 等 ish 系统。 Linux 上的典型方法解释得很好 here, and there is lots of good additional discussion on the topic here

典型的 signal(SIGPIPE, SIG_IGN) 在我尝试过的任何地方都有效,但(我相信)应该有一个更外科的解决方案来避免全局忽略 SIGPIPE。如果可能的话,避免平台特定的 pragma 也很好。

sigtimedwait() 功能似乎不存在于(当前?)macOS 版本中,因此跨平台解决方案看起来不太可能使用该方法。

sigwait() 函数似乎无处不在,但如果特定信号实际上没有挂起,它将永远阻塞。因此,下一个最佳方法似乎是使用 sigpending() 查看待处理的内容,然后 sigwait() 对其进行服务,这两种方法似乎都可用。

让我担心的是几乎没有(我能找到的)关于这个特定问题的文章,这通常表明我遗漏了一些非常明显的东西。

那么,对于上述用例,pthread_sigmask() / sigpending() / sigwait() / pthread_sigmask() 是一个不错的选择吗?或者是否有(非?)我应该注意的明显陷阱?

So, is pthread_sigmask() / sigpending() / sigwait() / pthread_sigmask() a good choice for the above use case? Or are there (non?)obvious pitfalls I should be aware of?

事实上 sigwait()sigtimedwait() 是在 POSIX 的同一版本中发布的。如果您希望通过依赖标准来实现可移植性,并且如果 macOS 因省略后者而无法符合标准,那么您应该担心它不符合标准的其他原因。事实上,还有 其他可能会影响您的不合规领域,但不一定与您提出的特定函数调用系列有关。

为了获得最佳的可移植性,我建议尽可能采用最简单的解决方案。在这种情况下,我会简单地忽略该信号(即将其处置设置为 SIG_IGN)。我推断您明白信号处置是每个进程的特征,而不是每个线程的特征,但那又怎样?您所有的 write() 都应该检查它们的 return 值以检测短写入和错误情况,如果它们正确地做到了这一点,那么它们将采取适当的行动而无需接收信号。