I've seen this question before, but still a bit confused: how would I create communication between child 开发者_StackOverflow中文版processes of the same parent? All I'm trying to do at the moment is passing a message from the first child process to the nth child process. My idea is to create n-1 pipes in the parent process and then redirect the parent's ends to the next child process. What I can't figure out is, how would we redirect the ends from the parent if the next child process hasn't been created? I feel there's an issue in the way I'm approaching this.
EDIT: My goal is to print the message that was passed from the first child process to the last one. It's a simple program.
You don't need to create the processes first. The solution is as follows: you first create all the needed pipes, save them in some array. Then you do a fork
, redirect input and output streams (for the child process) accordingly, close unused pipe ends and perform an exec
. Pipes can exist without the corresponding processes, they have buffers, so you can write to a pipe while nobody's still reading, it will be ok.
You should just be aware of closing unused id's before doing exec
. And be careful writing to a pipe which input endpoints (all the input endpoints) could become closed: it could result in a SIGPIPE
.
The code to setup a pipe and have stadin/stdout redirected to the pipe is.
In parent (before fork)
int p[2];
pipe(p);
In the child (after fork) to get the pipe as stdin
close(0);
dup(p[0]);
In the child (after fork) to get the pipe as stdout
close(1);
dup(p[1]);
You can start writing to the pipe as soon as it is created. However this child process which is writing to the pipe will pause as soon as the pipe-buffer is filled and until the other process is starting reading from the pipe.
Also look at the popen call as that may actually be a simpler version of what you need.
Rather than using un-named pipes, you may want to look into an alternate mechanism for inter-process communication such as using a FIFO, message-queue, or a socket using datagrams (i.e., UDP) that would allow you to write a "message" into the communication buffer, and then have another child read the message, see if it's for them and if it's not, have them place it back in the communicatons buffer for another child to read. Otherwise if the message is for them, they then accept it.
Your message can be a struct
that contains a sender ID, receiver ID, and then some buffer to hold a message, whether that's a string-type, etc.
The communications buffer can be setup by the parent, and inherited by the children.
In a simplified non-exec
case, you should do something like.
#define nproc 17
int pipes[nproc - 1][2];
int pids[nproc];
int i;
for( i = 0; i < nproc - 1; i++ ) {
pipe( pipes[i] );
}
int rank;
for( rank = 0; rank < nproc; rank++ ) {
pids[rank] = fork();
if( !pids[rank] ) {
if( rank == 0 ) {
write( pipe[rank][1], /* your message */ );
}
read( pipe[rank-1][0], /* read the message somewhere*/ );
if( rank < nproc - 1 ) {
write( pipe[rank][1], /* write the message to the next child process*/ );
} else {
// Here print the received message (it's already received above)
}
}
}
for( rank = 0; rank < nproc; ++rank ) {
wait( pids[rank] );
}
精彩评论