Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何为3个不同的事件(信号量、pthread条件和阻塞套接字recv)阻止单个线程?_Linux_Multithreading_Sockets_Posix_Semaphore - Fatal编程技术网

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

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使用的影响,非阻塞和轮询不在考虑范围之内,而由于延迟增加,在不同事件上使用单独的线程阻塞并不理想(一个线程从一个事件中解除阻塞最终会唤醒主线程) 如果这有帮助的话,代

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

  • 进程间信号量(sem\u wait())
  • pthread条件(pthread_cond_wait())
  • 来自套接字的recv()
  • 超时过期
  • 理想情况下,我希望有一种机制在发生上述任何一种情况时解除主线程的阻塞,比如带有适当超时参数的ppoll()。由于对CPU使用的影响,非阻塞和轮询不在考虑范围之内,而由于延迟增加,在不同事件上使用单独的线程阻塞并不理想(一个线程从一个事件中解除阻塞最终会唤醒主线程)

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


    提前感谢您的建议

    在类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时,我是否应该期望有任何性能(意味着延迟)损失?没关系,这里有一个非常全面的分析: