开发者

Can we obtain a file descriptor for a semaphore or condition variable?

I have an implementation of a bi-directional message channel which, to reduce overhead, I implemented as a couple of circular buffers of messages. To write from one end to the other you add the pointer to the message to one circular buffer and tweak the read and write indices for it. To write in the other direction you do the same for the other buffer and so on. The code is small and simple and it avoids the overheads of using a pipe or fifo, although possibly that might have been a better solution in some ways.

I implemented a poll on this by simply checking if there was a message waiting to be read, and if not doing a timed wait on a condition variable that gets signalled when a message is added to the relevant array.

Now I have an application that needs to wait on a socket (more or less) and on the message channel at the same time. I now wish I had used a fifo or pipe, but due t开发者_Python百科o overhead in getting the code changed (long story), it's not really feasible to rewrite it to use a fifo or pipe.

Is there any way to get a file descriptor associated with a conditional variable? If so it is easier to implement a poll on two file descriptors at once, one for the conditional variable and one for the socket.

Out of curiosity, and making this question more useful to others with a similar problem, is it possible to get a file descriptor associated with a semaphore so you could poll on the semaphore and a regular file descriptor at the same time?


Generally, no. But different OSes offer different solutions for the problem you have.

Windows

You can associate an event with a socket with WSAEventSelect and wait with WaitForMultipleObjectsEx for the data on the socket or mutex or semaphore event etc.

Linux

You can use the futex syscall with FUTEX_FD argument (however this has been removed from the kernel), or use eventfd to implement the condition variable.

And you can spawn a second thread that would be waiting on the condition variable, and signal the one waiting in select(). Or ask for signals when input is received on the socket, etc. See this related question.


A file descriptor is an index into a kernel-managed array of open files and similar objects (pipes, FIFOs, sockets), so it's not possible to associate a file descriptor with anything not managed by the kernel.

If your message channels and semaphores are entirely in user space (implemented in your own application with recourse to system calls), then you can't get a file descriptor for it. Sorry.


It's a bit of a hack, but you could replace your condition variable with a pipe. The read thread would poll/select on the read side and the socket. The thread that writes to your buffer also writes a byte to the pipe to signal there is stuff in the buffer.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜