【问题标题】:Can we obtain a file descriptor for a semaphore or condition variable?我们可以获取信号量或条件变量的文件描述符吗?
【发布时间】:2010-12-02 13:46:58
【问题描述】:

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

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

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

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

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

【问题讨论】:

  • 我猜你的解决方法是创建一个管道,然后启动一个线程等待 condvar 并在相关条件变为真时向管道写入一个字节。然后您可以轮询套接字和管道。如果您想概括该代码并将其称为“获取条件变量的 fd”,那么是的,您可以获取条件变量的 fd ;-)
  • @Steve,这比 JeremyP 的想法还要老套!创建一个线程?!?就为了这个!?我很高兴你在开玩笑的笑脸:)
  • @AlistairG:耸耸肩。您是说您不想更改发布 condvar 的现有代码的人,因此只需编写一个不同的接收器即可。当然,jpalacek 的想法是在 condvar 上正常等待,但接收套接字活动的信号以中断该等待,从而节省了线程。添加线程是将阻塞操作更改为异步操作的最常用方法,因此,除非您的系统上的线程限制较低,否则我认为没有必要对此感到歇斯底里:-)
  • 史蒂夫,您应该将其发布为答案。鉴于 OP 要求不解决根本问题,您的答案可能是最正确的。

标签: c multithreading


【解决方案1】:

一般来说,不会。但是不同的操作系统会针对您遇到的问题提供不同的解决方案。

窗口

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

Linux

您可以使用带有 FUTEX_FD 参数的 futex 系统调用(但是这已从内核中删除),或者使用 eventfd 来实现条件变量。

您可以生成第二个线程,该线程将在条件变量上等待,并在 select() 中发出等待的信号。或者在socket接收到输入时请求信号等。见this related question

【讨论】:

    【解决方案2】:

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

    如果您的消息通道和信号量完全位于用户空间中(通过系统调用在您自己的应用程序中实现),那么您将无法获得它的文件描述符。对不起。

    【讨论】:

    • 信号量/条件变量是一个内核对象。好吧,实际上它是分层在 pthreads 上的第三方代码,它分层在内核对象上,但是这些层都可以访问下面的层,所以我可以深入研究。这基本上让我回到了我开始的地方,即内核是否允许您获取对象的文件描述符。我猜由于文件描述符具有固有的读写属性,以及信号量和条件变量,因此不是 asnwer 。谢谢你的回答让我明白了。
    【解决方案3】:

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

    【讨论】:

    • 这个特殊的软件已经有太多的黑客攻击了。它崩溃太多了。这是一个团队开发原型的情况,然后管理层对产品开发施加了如此大的压力,以至于产品开发继续使用原型,而不是回到开始并正确编写它:(我不想谈论它。这也是郁闷。你的想法是可行的,但如果我要在那里放一个管道,我还不如用管道替换消息通道本身!
    猜你喜欢
    • 1970-01-01
    • 2010-11-17
    • 2020-07-12
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-11
    相关资源
    最近更新 更多