# Unix IPC implementation

This topic is 3078 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi ,

I am trying to understand at a low level how UNIX pipes are implemented. I am comfortable with the basics of them. i.e. In short , why are two file descriptors required? Why can't the same be achieved via a single fd ? Is this due to producer-consumer sync scenario?

Also I plan to implement the same in order to get a better understanding ? Can you guys suggest how can one go about it ? I read they are implemented using Unix sockets..

Another question: Why is it advisable to close a end of pipe from both child and parent ? Well in concept duplex pipe do sound better..

Cheers!

##### Share on other sites
You need two descriptors because a pipe has two flow directions; each direction has its own independent IO channel in a sense. This allows both processes to throw data at each other without getting in each others' way, while ensuring that if one process wants to read from the pipe, it has to wait until the other is done writing, and vice versa.

Pipe implementations depend on the platform. It's been a while since I've done any kernel hacking, but IIRC, pipes are actually implemented as their own entities at the kernel level, at least in the Linux and BSD flavors I'm familiar with. Sockets are a totally different beast, although they share some of the same internals on some OSes. Can't really say anything about how Windows does their pipes.

If you want to learn how they work, why not grab some kernel source for your favorite Unix flavor and study that? It isn't too terribly hard to get started: write a simple app using pipes, then look at each kernel function you invoke, and go hunt down the source for that function. I learned quite a bit about socket implementations doing that.

For your last question: a pipe has to be closed from both ends because the kernel has to know that both processes are finished with the involved data. Suppose the parent kills the pipe before the child is done reading; if the data just gets flushed, the child is hosed and loses important information, and so on.

##### Share on other sites
A Unix pipe is just a set of buffers with associated file descriptor table entries.

A Unix socket is a complex beast requiring several layers of wrappers, going through a subset of the BSD networking layers of the kernel.

Pipes are not implemented on top of Unix-domain sockets.

Separate file descriptors are required for each end of a pipe because one is read-only, the other is write-only. This has to do with the simplicity of design of pipes: they are extremely lightweight, and synchronizing bidirectional buffers would add unnecessary overhead. For the same reason, the pipe is not torn down until both ends are closed. Pipes are designed to be used across fork(2) calls.

##### Share on other sites
Thank you very much for your replies.

Quote:
 Original post by ApochPiQFor your last question: a pipe has to be closed from both ends because the kernel has to know that both processes are finished with the involved data. Suppose the parent kills the pipe before the child is done reading; if the data just gets flushed, the child is hosed and loses important information, and so on.

I am sorry , but i still do not understand. Taking an example.
int fd[2];pipe(fd);char buff[10];int len =10;pid = fork();if(pid ==0){  sleep(10);  read(fd[0],buff,len)}else{  write(fd[1],"hi",strlen("hi"));}

Since fd's are duplicated , the reference count should be 2 , and when parent exits, the read fd should still be valid right ? Please correct me if i am wrong, but this would lead to a condition where the process blocks (if looping on read))

[Edited by - _korg on July 10, 2010 3:38:38 PM]

1. 1
2. 2
3. 3
Rutin
13
4. 4
5. 5

• 26
• 11
• 9
• 9
• 11
• ### Forum Statistics

• Total Topics
633696
• Total Posts
3013401
×