tags:

views:

119

answers:

2

In a linux application I'm using pipes to pass information between threads.

The idea behind using pipes is that I can wait for multiple pipes at once using poll(2). That works well in practice, and my threads are sleeping most of the time. They only wake up if there is something to do.

In user-space the pipes look just like two file-handles. Now I wonder how much resources such a pipes use on the OS side.

Btw: In my application I only send single bytes every now and then. Think about my pipes as simple message queues that allow me to wake-up receiving threads, tell them to send some status-data or to terminate.

+5  A: 

No, I would not consider pipes "lightweight", but that doesn't necessarily mean they're the wrong answer for your application either.

Sending a byte over a pipe is going to require a minimum of 3 system calls (write,poll,read). Using an in-memory queue and pthread operations (mutex_lock, cond_signal) involves much less overhead. Open file descriptors definitely do consume kernel resources; that's why processes are typically limited to 256 open files by default (not that the limit can't be expanded where appropriate).

Still, the pipe/poll solution for inter-thread communication does have advantages too: particularly if you need to wait for input from a combination of sources (network + other threads).

David Gelhar
Why would it take 3 system calls? a blind `write()` call will block if the pipe's buffers are full. if each thread only needs to listen to its own pipe, you can drop the `poll()` as well, simply waiting for `read()` to succeed
Hasturkun
OP specifically said that he's using poll() to wait for multiple pipes from one consumer thread.
David Gelhar
I have to read and write to one file (/dev/ttySxx serial) *and* be able to respond to commands from another thread. Blocking is out of question. If I for example have a 10 megabyte write on the serial I can't wait until it is finished if the application tells me that it wants to abort the transfer. Therefore two non-blocking files that I poll for: One for the serial port and one to receive commands.
Nils Pipenbrinck
+1  A: 

Measure and you'll know. Full processes with pipes are sufficiently lightweight for lots of applications. Other applications require something lighter weight, like OS threads (pthreads being the popular choice for many Unix apps), or superlightweight, like a user-level threads package that never goes into kernel mode except to handle I/O. While the only way to know for sure is to measure, pipes are probably good enough for up to a few tens of threads, whereas you probably want user-level threads once you get to a few tens of thousands of threads. Exactly where the boundaries should be drawn using today's codes, I don't know. If I wanted to know, I would measure :-)

Norman Ramsey
I guess I'm confused. I think Linux's NPTL implementation is kernel-level. Does glibc provide a user-level implementation on top of that?
Wei Hu
@Wei: My mistake. Edited.
Norman Ramsey