linux - 如何为 3 个不同的事件(信号量、pthread 条件和阻塞套接字接收)阻塞单个线程?

标签 linux multithreading sockets posix semaphore

我有一个多线程系统,其中主线程必须在阻塞状态下等待以下 4 个事件之一发生:

  1. 进程间信号量(sem_wait())
  2. pthread 条件 (pthread_cond_wait())
  3. 从套接字接收()
  4. 超时到期

理想情况下,我希望有一种机制可以在发生上述任何情况时解除对主线程的阻塞,类似于具有适当超时参数的 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/

相关文章:

ios - NSOuputStream发送旧值- objective-c

java - apache.commons.net.ftp.FTPClient 没有将文件上传到所需的文件夹

php - 使用wget远程登录

android - 在linux中注册驱动程序

c# - db4o 客户端/服务器似乎一次只能处理一个查询?

Java 服务器-客户端 readLine() 方法

java - 通过udp传输文件

linux - 根据第一个文本文件的第一列合并两个未排序的文本文件并保留顺序

c# - .NET 4.0 和可怕的 OnUserPreferenceChanged 挂起

c++ - OpenMP 代码在线程池中执行