views:

25

answers:

2

I have two questions is one here.

On Windows, I am familiar with pipes and how they work. However, I am curious as to what mechanism the OS uses to notify the recipient thread of a message arrival.

Does the thread "poll & sleep" continuously for data? Does the OS check to see if the thread is sleeping and wake it up? Or is there some other mechanism used?

Specifically, I want to build an IPC system where many threads need to pass messages. I don't need to use pipes, but I do need to know the most efficient notification method possible.

A: 

The developer can decide how they want to work with the pipe, whether they will sleep/poll or else they want to call blocking functions and wait until the data is available.

About the mechanism that the pipe has for waking up the process --assuming that the process is in a blocking read call-- it is not the pipe, but the OS the one that takes charge, like in any other OS call: it registers the operation and blocks the process/thread until the data is available. When the data is available, it completes the system call.

David Rodríguez - dribeas
Since my application for this is self-managed IPC within 1 process, it seems that a "wake up, you have work" policy would be the most efficient.A thread would check various input buffers for data (1 for each possible sender, thus negating the need for locks; alternatively a synchronized method - but this is slow), and then sleep when it finds none. The sender would signal the system to wake up the recipient if needed.Or am I off in the wrong direction here?
IanC
If you are working within a single process, then this is probably not the best solution, you can use a multithread message queue (there are different implementations in libraries already available) that can be used to communicate among threads in a single process.
David Rodríguez - dribeas
Thanks David - I'll see what I can find.
IanC
A: 

This is an answer for Unix. I'd lay good money on Windows being pretty similar as the solution has been around a long time and is well known to be robust. The details will vary a bit (different API calls, specifics of semantics, etc.)

It depends on whether the other end is using the pipe's file descriptor in blocking or non-blocking mode.

In blocking mode, the process is waiting in the OS kernel for the data to become available. The way in which notification happens there depends on the OS. Chances are it involves a queue of processes that are considered to be runnable, and everything's made simpler by the fact that the kernel can (largely) control what interrupts it. In a simple (single processor) implementation you could go for something as trivial as noting on write to the pipe that the other process is waiting to read from it (via some kind of “interest set”), and so marking the reader as runnable at that point (at which time it becomes up to the scheduler to decide).

In non-blocking mode, either the process is polling from time to time (yuck!) or they're using a system call like select() or poll() (there are some higher-performance variants too). That's very much like the Windows call WaitForMultipleObjects() and works just great with pipes. That in turn ends up back at that runnable process queue, the interest set, and the scheduler.

It also doesn't really matter too much whether it's blocking because the pipe is full or the pipe is empty, as the control flow is pretty much symmetric between readers and writers. (Unlike the data flow, of course.)

Donal Fellows