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

时间:2017-09-29 15:31:01

标签: linux multithreading sockets posix semaphore

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

  1. 进程间信号量(sem_wait())
  2. pthread条件(pthread_cond_wait())
  3. 来自套接字的recv()
  4. 超时到期
  5. 理想情况下,我希望在上述任何一种情况发生时解锁主线程的机制,类似于具有合适超时参数的ppoll()。由于对CPU使用的影响,非阻塞和轮询是不合适的,而由于延迟增加而在不同事件上阻塞单独的线程并不理想(一个线程从其中一个事件解除阻塞最终应该唤醒主要一)。

    代码几乎完全在Linux下使用gcc工具链编译,如果这有帮助,但是如果可能的话,一些可移植性会很好。

    提前感谢任何建议

1 个答案:

答案 0 :(得分:1)

在类Unix系统上等待多种类型对象的机制并不是那么好。一般而言,我们的想法是尽可能使用IPC的文件描述符而不是多种不同的IPC机制。

从您的评论中,您可以编辑或更改条件变量,但不能发出信号信号的代码。所以我推荐的是以下内容。

将条件变量更改为管道(以获得更多可移植性)或eventfd(2)对象(特定于Linux)。只要想要通知主线程,通知线程就会写入管道。这将允许您在该管道和套接字上的主线程中select(2)poll(2)或其他任何内容。

因为你坚持使用信号量,我认为最好的选择是创建另一个线程,其唯一目的是使用sem_wait()等待信号量,然后写入另一个管道或{{1当任何进程正在执行eventfd(2)通知它时的对象。在主线程中,只需将此其他文件描述符添加到sem_post()集。

因此,您将拥有三个描述符:一个用于套接字,一个用于取代条件变量,另一个用于在信号量递增时写入。然后,您可以使用您喜欢的I / O多路复用方法等待所有这三种方法,并直接包含您想要的任何超时。