怎样标准输出链增长在一个子进程中下再儿童标准输入? [英] How do I chain stdout in one child process to stdin in another child in C?

查看:99
本文介绍了怎样标准输出链增长在一个子进程中下再儿童标准输入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直插科打诨用C试图找出如何做到这一点。比方说,我有我的主程序,父进程。父创建三个子进程,每一个最终将运行程序(但现在这并不重要)。我想要做的就是让这个第一个孩子的标准输出将被第二个孩子的标准输入接收。第二个孩子的标准输出然后由第三个孩子的标准输入接收。
父进程的标准输入/输出不乱用的。

到目前为止,我所得到的是

 管(procpipe);parentPid = GETPID();对于(I = 0; I&下; 3;我+ +)
{
    如果(GETPID()== parentPid)
    {
        孩子[我] = fork()的;
        如果(孩子[我] == 0)
        {
            为mynumber = I + 1;
        }
    }
}

不过,从那里我有点坚持至于如何使用dup2正确地分配我管,并在其中我的code的部分插入。有很多关于谷歌的例子和这个网站如何从父到子管,但我还没有看到一个会告诉我究竟是如何一个孩子的标准输出连接到另一个孩子的标准输入。

编辑:
忘了提:假设我所有的变量都正确初始化。通过int'mynumber的'是这么一个子进程知道在创建哪个号码是,这样我就可以通过

给它的指令

 如果(mynumber的==什么)


解决方案

所以,你必须创建若干子进程的循环。每个子进程将使用的两个的管道:从previous读取和写入到下一个。要建立管阅读最终你需要关闭管道的写端和 dup2 读端插入标准输入。类似的,其中的过程会写管道。

 无效set_read为(int * lpipe)
{
dup2(lpipe [0],STDIN_FILENO);
关闭(lpipe [0]); //我们有一个副本了,所以关闭
关闭(lpipe [1]); //没有使用这个目的
}无效set_write为(int * rpipe)
{
dup2(rpipe [1],STDOUT_FILENO);
关闭(rpipe [0]); //没有使用这个目的
关闭(rpipe [1]); //我们有一个副本了,所以关闭
}

在派生每次需要管道连接到它。孩子

 无效fork_and_chain为(int * lpipe,为int * rpipe)
{
如果(!叉())
{
如果(lpipe)//有从previous工艺管道
set_read(lpipe);
        //否则你可能想从别的地​​方重定向输入启动
如果(rpipe)//有一个管到下一个处理
set_write(rpipe);
        //否则你可能想出来重定向到其他地方进行到底        //等等做你的东西
        //并确保子进程在这里终止
        //所以不会继续运行链接code
}
}

通过本在手,你现在可以写一个循环,不断地叉,附加管道,然后重用输出管道作为下一个输入管道。当然,一旦管道的两端已经连接到子进程,家长不应该把它打开自己。

  //这里假设有要链接的至少两个进程:)//两个管道:一个来自该链中的previous,一个链中的下一个
INT lpipe [2],rpipe [2];//创建第一个输出管道
管(rpipe);//第一个孩子需要从其他地方输入
fork_and_chain(NULL,rpipe);//输出管道将成为下一个过程的输入。
lpipe [0] = rpipe [0];
lpipe [1] = rpipe [1];//链所有,但第一个和最后一个孩子
对于(i = 1; I< N - 1;我++)
{
管(rpipe); //使下输出管道
fork_and_chain(lpipe,rpipe);
    关闭(lpipe [0]); //两端连接,关闭它们的父
    关闭(lpipe [1]);
lpipe [0] = rpipe [0]; //输出管道成为输入管道
lpipe [1] = rpipe [1];
}//叉最后一个,其输出端变为别的地方
fork_and_chain(lpipe,NULL);
关闭(lpipe [0]);
关闭(lpipe [1]);

收盘位是非常重要的!当你与一个开放的管叉,将有四开文件描述符:两个在父进程,和另外两个人对孩子的过程。你必须关闭所有那些你将不会被使用。这就是为什么code就永远关闭在子进程管道的两端无关,并且两端父。

另外请注意,我的第一个和最后一个流程给予特殊待遇,因为我不知道在哪里了链中的投入将来自何方,何地输出去。

I've been messing around in C trying to figure out how to do this. 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. 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.

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. 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.

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

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. 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.

这篇关于怎样标准输出链增长在一个子进程中下再儿童标准输入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆