Is it possible to have a channel between two child processes created by the same parent (LINUX, POSIX)

I have several forked children of the same parent, and I'm trying to build a pipe connection between all of these child processes, such as a linked list structure. Child 1 sends data to child2, child 2 - child 3 .... child N to child 1. Is there a proper way to do this?

In addition, if I create and link between processes, how to make the parent β€œwait” the whole process to complete its task, since wait() or waitpid() waiting for the first completed process, but I need to wait for them all. This is another question that arises.

Thanks...

+8
c linux pipe ipc
source share
3 answers

This is essentially what the shell does if you build a redirect chain, i.e. something like

 ls | grep foo | sort | uniq 

In Unix programming, there are several excellent introduction texts in which a simple shell is implemented through the book. And one of the tasks of the shell is redirection. One of these books is Linux Application Programming by Michael C. Johnson and Eric W. Throne.

Book Homepage: http://ladweb.net/

To create a redirect chain for N processes, you will need N-1 pipes. For each redirection, you create a pipe using the pipe(int fds[2]) system call pipe(int fds[2]) . After fork() ing, but before execv ing, use dup2(int from, int to) to "connect" the end of the pipe to the standard input (0) or standard output of each process. Here's too simplified code without error checking:

 int pipe_A[2]; int pipe_B[2]; pipe(pipe_A); pipe(pipe_B); pid_t pid_A, pid_B, pid_C; if( !(pid_A = fork()) ) { dup2(pipe_A[1], 1); /* redirect standard output to pipe_A write end */ execv(...); } if( !(pid_B = fork()) ) { dup2(pipe_A[0], 0); /* redirect standard input to pipe_A read end */ dup2(pipe_B[1], 1); /* redirect standard output to pipe_B write end */ execv(...); } if( !(pid_C = fork()) ) { dup2(pipe_B[0], 0); /* redirect standard input to pipe_B read end */ execv(...); } 

Note that the pipe array indexes were chosen so that they reflect the standard file I / O descriptors if they are used to redirect stdio. This choice was not arbitrary.

Of course, you can connect pipes to any file descriptors (for example, there are some applications that expect their parent to open, say fd 3 and 4 connected to pipes), and most shells directly support this (for example, 1> & 3 will redirect stdout to fd 3). However, the array indices for pipe(int fds[2]) are 0 and 1, of course. I just talk about it because I had cultural programming students who thoughtlessly used target fds also for the syscall array for pipes.

To wait until all children finish using waitpid(-1, NULL, 0) , I think this meant -1 to my pre-responder, which means: wait until all the child processes are complete. Another option called wait() in a loop that returns the pid of the just finished child. If you call again and the child still works, he will be blocked again. If the child is left, he will return -1; I prefer waitpid solution.

+17
source share

Yes, it's pretty simple, you just need to create all the channels in the parent device and don't forget to close the pipes / pipe ends in the child (ren) that you don't need.

Leaving pipe FDs open in children who do not use them is FAIL, as this can make others wait forever for the end of the pipe. All authors must close before the reader receives EOF.

+3
source share

First create all the pipes, and then create all the children with the corresponding pipe ends in FD 0 and 1.

As for the wait, just keep waiting until it returns -1.

+2
source share

All Articles