Linux 如何为3个不同的事件(信号量、pthread条件和阻塞套接字recv)阻止单个线程?
我有一个多线程系统,其中主线程必须在阻塞状态下等待以下4个事件之一发生:Linux 如何为3个不同的事件(信号量、pthread条件和阻塞套接字recv)阻止单个线程?,linux,multithreading,sockets,posix,semaphore,Linux,Multithreading,Sockets,Posix,Semaphore,我有一个多线程系统,其中主线程必须在阻塞状态下等待以下4个事件之一发生: 进程间信号量(sem\u wait()) pthread条件(pthread_cond_wait()) 来自套接字的recv() 超时过期 理想情况下,我希望有一种机制在发生上述任何一种情况时解除主线程的阻塞,比如带有适当超时参数的ppoll()。由于对CPU使用的影响,非阻塞和轮询不在考虑范围之内,而由于延迟增加,在不同事件上使用单独的线程阻塞并不理想(一个线程从一个事件中解除阻塞最终会唤醒主线程) 如果这有帮助的话,代
提前感谢您的建议在类Unix系统上等待多种类型对象的机制并没有那么好。一般来说,我们的想法是尽可能使用IPC的文件描述符,而不是使用多种不同的IPC机制 从您的评论中,听起来您可以编辑或更改条件变量,但不能编辑或更改信号量的代码。因此,我建议如下 将条件变量更改为管道(以提高可移植性)或
eventfd(2)
对象(特定于Linux)。每当通知线程想要向主线程发送信号时,它都会写入管道。这将允许您选择(2)
或轮询(2)
或该管道和插座主螺纹中的任何内容
由于您一直在使用信号量,我认为最好的选择是创建另一个线程,其唯一目的是使用sem\u wait()
等待信号量,然后在任何进程通知它时,将其写入另一个管道或eventfd(2)
对象。在主线程中,只需将另一个文件描述符添加到select(2)
set
因此,您将有三个描述符:一个用于套接字,一个代替条件变量,另一个在信号量递增时写入。然后,您可以使用您最喜欢的I/O多路复用方法等待所有三个线程,并直接包括您想要的任何超时。您能够编辑后台线程的代码吗?也就是说,你能在后台线程中修改信号量和条件变量的地方添加更多代码吗?@bnaecker我可以访问线程内同步代码(本质上是通知pthread条件变量的线程),但不能访问进程间信号量,就像sem_post()一样在这个信号灯上,我等待的是第三方,不在我的控制范围内。谢谢。用管道替换pthread条件很简单。我们使用该条件向主线程发出作业结束的信号,因此管道可以轻松地执行此操作。但是,我想知道,在从pthread cond_wait切换到阻塞管道上的recv时,我是否应该期望有任何性能(意味着延迟)损失?没关系,这里有一个非常全面的分析: