我以前见过这个问题,但仍然有点困惑:如何在同一个父级的子进程之间创建通信?我现在要做的就是将消息从第一个子进程传递到第n个子进程。我的想法是在父进程中创建n-1个管道,然后将父进程重定向到下一个子进程。我无法弄清楚的是,如果尚未创建下一个子进程,我们如何从父进程重定向结束?我觉得我接近这个问题的方式存在问题。
编辑:我的目标是打印从第一个子进程传递到最后一个进程的消息。这是一个简单的程序。
答案 0 :(得分:1)
您不需要先创建流程。解决方案如下:首先创建所有需要的管道,将它们保存在某个阵列中。然后,您执行fork
,相应地重定向输入和输出流(针对子流程),关闭未使用的管道端并执行exec
。管道可以在没有相应进程的情况下存在,它们具有缓冲区,因此您可以在没有人仍在阅读的情况下写入管道,这样就可以了。
在执行exec
之前,您应该知道关闭未使用的ID。并且要小心写入输入端点(所有输入端点)可能会关闭的管道:它可能会导致SIGPIPE
。
答案 1 :(得分:0)
设置管道并将stadin / stdout重定向到管道的代码是。
在父母(叉前)
int p[2];
pipe(p);
在子级(fork之后)将管道作为stdin
close(0);
dup(p[0]);
在子(在fork之后)将管道作为标准输出
close(1);
dup(p[1]);
您可以在创建管道后立即开始写入管道。但是,只要管道缓冲区被填满,并且另一个进程开始从管道读取,这个写入管道的子进程将暂停。
另外>> popen call ,因为这实际上可能是您需要的更简单的版本。
答案 2 :(得分:0)
您可能希望查看进程间通信的替代机制,例如使用FIFO,消息队列或使用数据报(即UDP)的套接字,而不是使用未命名的管道。将一条“消息”写入通信缓冲区,然后让另一个孩子读取该消息,看看它是否适合他们,如果不是,请让他们将其放回通信缓冲区以供另一个孩子阅读。否则,如果消息是为他们,他们然后接受它。
您的邮件可以是struct
,其中包含发件人ID,收件人ID,然后是一些用于保存邮件的缓冲区,无论是字符串类型等等。
通信缓冲区可由父级设置,并由子级继承。
答案 3 :(得分:0)
在简化的非exec
案例中,您应该执行类似的操作。
#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] );
}