C中子进程之间的管道

时间:2011-07-25 18:13:29

标签: c unix process pipe

我以前见过这个问题,但仍然有点困惑:如何在同一个父级的子进程之间创建通信?我现在要做的就是将消息从第一个子进程传递到第n个子进程。我的想法是在父进程中创建n-1个管道,然后将父进程重定向到下一个子进程。我无法弄清楚的是,如果尚未创建下一个子进程,我们如何从父进程重定向结束?我觉得我接近这个问题的方式存在问题。

编辑:我的目标是打印从第一个子进程传递到最后一个进程的消息。这是一个简单的程序。

4 个答案:

答案 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] );
}