如何将一个子进程中的stdout链接到C中另一个子进程中的stdin?

我一直在乱搞C试图弄清楚如何做到这一点。 假设我有我的主程序,即父进程。 父级创建了三个子进程,每个进程最终将运行程序(但现在这并不重要)。 我想做的就是让第二个孩子的stdin接收第一个孩子的stdout。 然后第三个孩子的标准输出将接收第二个孩子的标准输出。 父进程的stdin / stdout根本没有搞乱。

到目前为止,我得到的是

pipe(procpipe); parentPid = getpid(); for(i = 0; i < 3; i++) { if(getpid() == parentPid) { child[i] = fork(); if(child[i] == 0) { mynumber = i+1; } } } 

但是从那里开始,我有点担心如何使用dup2来正确分配我的管道,以及在我的代码的哪一部分插入它。 谷歌和这个网站上有很多关于如何从父母到孩子的管道的例子,但是我还没有看到一个会告诉我如何将孩子的标准输出连接到另一个孩子的标准输入的确切信息。

编辑:忘记提及:假设我的所有变量都已正确初始化。 int’mynumber’是这样的子进程在创建时知道它是哪个数字,所以我可以通过它给出指令

 if(mynumber == whatever) 

所以你有一个创建几个子进程的循环。 这些子进程中的每一个都将使用两个管道:从先前读取并写入下一个。 要为读取端设置管道,您需要关闭管道的写入端,并将读取端dup2到stdin中。 类似于进程将要写入的管道。

 void set_read(int* lpipe) {    dup2(lpipe[0], STDIN_FILENO);    close(lpipe[0]); // we have a copy already, so close it    close(lpipe[1]); // not using this end } void set_write(int* rpipe) {    dup2(rpipe[1], STDOUT_FILENO);    close(rpipe[0]); // not using this end    close(rpipe[1]); // we have a copy already, so close it } 

当您分叉每个孩子时,您需要将管道连接到它。

 void fork_and_chain(int* lpipe, int* rpipe) {    if(!fork())    {        if(lpipe) // there's a pipe from the previous process            set_read(lpipe); // else you may want to redirect input from somewhere else for the start        if(rpipe) // there's a pipe to the next process            set_write(rpipe); // else you may want to redirect out to somewhere else for the end // blah do your stuff // and make sure the child process terminates in here // so it won't continue running the chaining code    } } 

有了这个,您现在可以编写一个循环,连续分叉,附加管道,然后重新使用输出管道作为下一个输入管道。 当然,一旦管道的两端都连接到子进程,父进程就不应该让它自己打开。

 // This assumes there are at least two processes to be chained :) // two pipes: one from the previous in the chain, one to the next in the chain int lpipe[2], rpipe[2]; // create the first output pipe pipe(rpipe); // first child takes input from somewhere else fork_and_chain(NULL, rpipe); // output pipe becomes input for the next process. lpipe[0] = rpipe[0]; lpipe[1] = rpipe[1]; // chain all but the first and last children for(i = 1; i < N - 1; i++) {    pipe(rpipe); // make the next output pipe    fork_and_chain(lpipe, rpipe); close(lpipe[0]); // both ends are attached, close them on parent close(lpipe[1]);    lpipe[0] = rpipe[0]; // output pipe becomes input pipe    lpipe[1] = rpipe[1]; } // fork the last one, its output goes somewhere else  fork_and_chain(lpipe, NULL); close(lpipe[0]); close(lpipe[1]); 

关闭位非常重要! 当您使用打开的管道进行分叉时,将有四个打开的文件描述符:两个在父进程上,另外两个在子进程上。 你必须关闭所有你不会使用的东西。 这就是为什么上面的代码总是关闭子进程中管道的无关端,并且两者都以父进程结束。

另请注意,我正在对第一个和最后一个进程进行特殊处理,因为我不知道链的输入将来自何处,以及输出将在何处。