简体   繁体   English

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

[英]How do I chain stdout in one child process to stdin in another child in C?

I've been messing around in C trying to figure out how to do this. 我一直在乱搞C试图弄清楚如何做到这一点。 Let's say I have my main program, the parent process. 假设我有我的主程序,即父进程。 The parent creates three child processes, each of which will eventually run programs (but that's not important right now). 父级创建了三个子进程,每个进程最终都会运行程序(但现在这并不重要)。 What I'd like to do is make it so that the first child's stdout will be received by the second child's stdin. 我想做的就是让第二个孩子的stdin接收第一个孩子的stdout。 The second child's stdout will then be received by the third child's stdin. 然后第三个孩子的标准输出将接收第二个孩子的标准输出。 The parent process's stdin/stdout aren't messed with at all. 父进程的stdin / stdout根本没有搞乱。

So far, what I've got is 到目前为止,我得到的是

pipe(procpipe);

parentPid = getpid();

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

But from there I'm kind of stuck as to how to use dup2 to properly assign my pipes, and in which section of my code to insert it. 但是从那里开始,我有点担心如何使用dup2来正确分配我的管道,以及在我的代码的哪个部分插入它。 There are lots of examples on Google and this website of how to pipe from a parent to a child, but I'm yet to see one that will tell me exactly how to connect a child's stdout to another child's stdin. 谷歌和这个网站上有很多关于如何从父母到孩子的管道的例子,但是我还没有看到一个会告诉我如何将孩子的stdout连接到另一个孩子的stdin。

Edit: Forgot to mention: assume all my variables are properly initialised. 编辑:忘记提及:假设我的所有变量都已正确初始化。 The int 'mynumber' is so a child process knows upon creation which number it is, so I can give it instructions via int'mynumber'是这样的子进程在创建时就知道它是哪个数字,所以我可以通过它给出指令

if(mynumber == whatever)

So you have a loop that creates several child processes. 所以你有一个创建几个子进程的循环。 Each of these child processes will be using two pipes: read from previous and write to the next. 这些子进程中的每一个都将使用两个管道:从先前读取并写入下一个。 To set up a pipe for the reading end you need to close the write end of the pipe, and dup2 the read end into the stdin. 要为读取端设置管道,您需要关闭管道的写入端,并将读取端dup2到stdin中。 Similar for the pipe where the process will be writing. 类似于进程将写入的管道。

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
}

When you fork each children you need to attach the pipes to 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
    }
}

With this in hand you can now write a loop that continuously forks, attaches the pipes, and then reuses the output pipe as the input pipe for the next one. 有了这个,您现在可以编写一个循环,连续分叉,附加管道,然后重新使用输出管道作为下一个输入管道。 Of course, once both ends of a pipe have been connected to child processes, the parent should not leave it open for itself. 当然,一旦管道的两端都连接到子进程,父进程就不应该让它自己打开。

// 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]);

The closing bits are very important! 关闭位非常重要! When you fork with an open pipe, there will be four open file descriptors: two on the parent process, and two others on the child process. 当您使用打开的管道进行分叉时,将有四个打开的文件描述符:两个在父进程上,另外两个在子进程上。 You have to close all of those you won't be using. 你必须关闭所有你不会使用的东西。 That's why the code above always closes the irrelevant ends of the pipes in the child processes, and both ends on the parent. 这就是为什么上面的代码总是关闭子进程中管道的无关端,并且两者都以父进程结束。

Also note that I am giving special treatment to the first and the last processes, because I don't know where the input for the chain will come from, and where the output will go to. 另请注意,我正在对第一个和最后一个进程进行特殊处理,因为我不知道链的输入将来自何处以及输出将在何处。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 C 程序中动态链接 unix 实用程序命令,将子进程的标准输出连接到父进程的标准输入? - How can i dynamically chain unix utility commands in C program wiring stdout of child process to stdin of parent process? 与子进程stdout / stdin通信 - Communicate with child process stdout/stdin 在C语言的孩子中重定向stdin和stdout - Redirect stdin and stdout in child in c 将子进程的标准输入和标准输出重定向到管道 - Redirect child process's stdin and stdout to pipes 异步与子进程的stdin / stdout通信 - Communicate with the stdin/stdout of a child process asynchronously 在Windows中,如何创建子进程并捕获其stdin,stdout和stderr,而无需复制任何可继承的句柄? - In Windows, how can one create a child process and capture its stdin, stdout, and stderr, without duplicating any inheritable handles? 如何将STDIN传递给子进程? - How to pass STDIN to child process? 子进程如何从管道读取stdout,而父进程如何将stdin写入管道? - How can the child process read stdout from the pipe and the parent process write stdin to the pipe? Linux 3.0:使用管道stdin / stdout执行子进程 - Linux 3.0: Executing child process with piped stdin/stdout 子进程(通过CreateProcess)通过重定向的stdout和stdin停滞在getch()上 - Child process (via CreateProcess) stalls on getch() with redirected stdout and stdin
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM