我有一个多线程系统,其中主线程必须在阻塞状态下等待以下 4 个事件之一发生:
- 进程间信号量(sem_wait())
- pthread 条件 (pthread_cond_wait())
- 从套接字接收()
- 超时到期
理想情况下,我希望有一种机制可以在发生上述任何情况时解除对主线程的阻塞,类似于具有适当超时参数的 ppoll()。由于对 CPU 使用率的影响,非阻塞和轮询不在考虑范围之内,同时由于延迟增加,让不同的线程阻塞不同的事件并不理想(一个线程从一个事件中解除阻塞最终应该唤醒主线程一)。
代码将几乎完全在 Linux 下使用 gcc 工具链编译,如果这有帮助的话,但如果可能的话,一些可移植性会很好。
提前感谢您的任何建议
最佳答案
在类 Unix 系统上等待多种类型对象的机制不是很好。一般来说,想法是尽可能为 IPC 使用文件描述符,而不是使用多种不同的 IPC 机制。
根据您的评论,听起来您可以编辑或更改条件变量,但不能编辑或更改发出信号量信号的代码。所以我推荐的是如下内容。
将条件变量更改为管道(为了更好的可移植性)或 eventfd(2)
对象(特定于 Linux)。通知线程在它想要向主线程发送信号时写入管道。这将允许您在该管道和套接字的主线程中执行 select(2)
或 poll(2)
或任何操作。
因为你被信号量所困,我认为最好的选择是创建另一个线程,其唯一目的是使用 sem_wait()
等待信号量,然后写入另一个线程管道或 eventfd(2)
对象,当它被正在执行 sem_post()
的任何进程通知时。在主线程中,只需将这个其他文件描述符添加到您的 select(2)
集。
因此您将拥有三个描述符:一个用于套接字,一个代替条件变量,另一个在信号量递增时写入。然后,您可以使用您最喜欢的 I/O 多路复用方法等待所有三个,并直接包括您想要的任何超时。
关于linux - 如何为 3 个不同的事件(信号量、pthread 条件和阻塞套接字接收)阻塞单个线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46492221/