我们可以获取信号量或条件变量的文件描述符吗?

我有一个双向消息通道的实现,为了减少开销,我实现了几个循环的消息缓冲区。 要从一端写入另一端,将指向消息的指针添加到一个循环缓冲区,并调整其读取和写入索引。 要向另一个方向写入,请对其他缓冲区执行相同操作,依此类推。 代码小而简单,它避免了使用管道或fifo的开销,尽管可能在某些方面可能是更好的解决方案。

我通过简单地检查是否存在等待读取的消息,以及如果没有对在将消息添加到相关arrays时发出信号的条件变量进行定时等待来实现对此的轮询。

现在我有一个应用程序需要在套接字(或多或少)上同时等待消息通道。 我现在希望我使用过fifo或pipe,但由于代码更改的开销(长篇故事),重写它以使用fifo或pipe是不可行的。

有没有办法获得与条件变量关联的文件描述符? 如果是这样,一次对两个文件描述符实现轮询更容易,一个用于条件变量,一个用于套接字。

出于好奇,并使这个问题对于具有类似问题的其他人更有用,是否可以获得与信号量相关联的文件描述符,以便您可以同时轮询信号量和常规文件描述符?

一般来说,没有。 但不同的操作系统为您遇到的问题提供了不同的解决方案。

视窗

您可以使用WSAEventSelect将事件与套接字关联,并使用WaitForMultipleObjectsEx等待套接字或互斥或信号量事件等上的数据。

Linux的

您可以将futex系统调用与FUTEX_FD参数一起使用(但是已从内核中删除),或使用eventfd实现条件变量。

并且你可以产生第二个线程,它将等待条件变量,并发出一个在select()中等待的信号。 或者在sockets上接收到输入等时询问信号。请参阅此相关问题 。

文件描述符是内核管理的打开文件和类似对象(管道,FIFO,套接字)数组的索引,因此无法将文件描述符与内核管理的任何内容关联起来。

如果您的消息通道和信号量完全在用户空间中(在您自己的应用程序中使用系统调用实现),那么您无法获取它的文件描述符。 抱歉。

这有点像黑客,但你可以用管道替换你的条件变量。 读线程将在读取端和套接字上轮询/选择。 写入缓冲区的线程也会向管道写入一个字节,以指示缓冲区中有东西。