Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C中子进程之间的管道_C_Unix_Process_Pipe - Fatal编程技术网

C中子进程之间的管道

C中子进程之间的管道,c,unix,process,pipe,C,Unix,Process,Pipe,我以前见过这个问题,但仍然有点困惑:如何在同一父进程的子进程之间创建通信?目前我所要做的就是将消息从第一个子进程传递到第n个子进程。我的想法是在父进程中创建n-1个管道,然后将父进程的端点重定向到下一个子进程。我不明白的是,如果没有创建下一个子进程,我们如何从父进程重定向端点?我觉得我处理这件事的方式有问题 编辑:我的目标是打印从第一个子进程传递到最后一个子进程的消息。这是一个简单的程序。设置管道并将statin/stdout重定向到管道的代码是 在父级中(fork之前) 在子对象(fork之后

我以前见过这个问题,但仍然有点困惑:如何在同一父进程的子进程之间创建通信?目前我所要做的就是将消息从第一个子进程传递到第n个子进程。我的想法是在父进程中创建n-1个管道,然后将父进程的端点重定向到下一个子进程。我不明白的是,如果没有创建下一个子进程,我们如何从父进程重定向端点?我觉得我处理这件事的方式有问题


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

设置管道并将statin/stdout重定向到管道的代码是

在父级中(fork之前)

在子对象(fork之后)中获取管道作为stdin

   close(0);
   dup(p[0]);
在子对象(fork之后)中获取管道作为标准输出

  close(1);
  dup(p[1]);
创建管道后,可以立即开始向其写入。但是,写入管道的子进程将在管道缓冲区填满后立即暂停,直到另一个进程开始从管道读取


还可以查看,因为这实际上可能是您需要的更简单版本。

设置管道并将statin/stdout重定向到管道的代码是

在父级中(fork之前)

在子对象(fork之后)中获取管道作为stdin

   close(0);
   dup(p[0]);
在子对象(fork之后)中获取管道作为标准输出

  close(1);
  dup(p[1]);
创建管道后,可以立即开始向其写入。但是,写入管道的子进程将在管道缓冲区填满后立即暂停,直到另一个进程开始从管道读取


还可以查看,因为这实际上可能是您需要的更简单版本。

您不需要先创建流程。解决方案如下:首先创建所有需要的管道,将它们保存在某个数组中。然后执行
fork
,相应地重定向输入和输出流(用于子进程),关闭未使用的管道末端,并执行
exec
。管道可以在没有相应进程的情况下存在,它们有缓冲区,因此您可以在没有人还在读取的情况下写入管道,这样就可以了


在执行
exec
之前,您应该注意关闭未使用的id。并且要小心写入一个输入端点(所有输入端点)可能会关闭的管道:这可能会导致一个
SIGPIPE

您不需要先创建流程。解决方案如下:首先创建所有需要的管道,将它们保存在某个数组中。然后执行
fork
,相应地重定向输入和输出流(用于子进程),关闭未使用的管道末端,并执行
exec
。管道可以在没有相应进程的情况下存在,它们有缓冲区,因此您可以在没有人还在读取的情况下写入管道,这样就可以了


在执行
exec
之前,您应该注意关闭未使用的id。要小心写入一个输入端点(所有输入端点)可能会关闭的管道:这可能会导致一个
SIGPIPE

而不是使用未命名的管道,您可能需要研究进程间通信的替代机制,例如使用FIFO、消息队列或使用数据报(即UDP)的套接字这将允许您将“消息”写入通信缓冲区,然后让另一个孩子阅读消息,查看消息是否为他们所用,如果不是,则让他们将其放回通信缓冲区,以便另一个孩子阅读。否则,如果消息是给他们的,他们就会接受它

您的消息可以是一个
struct
,它包含发送者ID、接收者ID,然后是一些用来保存消息的缓冲区,无论是字符串类型,等等


通信缓冲区可以由父级设置,并由子级继承。

您可能希望研究进程间通信的替代机制,例如使用FIFO、消息队列或使用数据报(即UDP)的套接字,以允许您编写“消息”进入通信缓冲区,然后让另一个孩子阅读消息,看看消息是否适合他们,如果不是,让他们将消息放回通信缓冲区,让另一个孩子阅读。否则,如果消息是给他们的,他们就会接受它

您的消息可以是一个
struct
,它包含发送者ID、接收者ID,然后是一些用来保存消息的缓冲区,无论是字符串类型,等等


通信缓冲区可以由父级设置,并由子级继承。

在简化的非执行情况下,您应该执行以下操作

#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] );
}
#定义nproc 17
国际管道[nproc-1][2];
int pids[nproc];
int i;
对于(i=0;i
在简化的非
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] );
}
#定义nproc 17
国际管道[nproc-1][2];
int pids[nproc];
int i;
对于(i=0;i