简体   繁体   English

在C linux中使用fork进行两次管道传输

[英]piping two times using fork in C linux

I am trying to rewrite ac program that do something like ls|wc|wc , I already did it for ls|wc , it worked fine, but I can't figure out why my program stops at the child in the indicated line. 我正在尝试重写一个执行ls | wc | wc之类的ac程序,我已经为ls | wc做过它,它可以正常工作,但是我不知道为什么我的程序在指示的行中停留在孩子身上。 please help! 请帮忙!

int main (void)
{
    pid_t pid_fils, pid_pfils;

    int fd[2], fd2[2];

    if(pipe(fd)==-1 || pipe(fd2)==-1)
    {
        printf("pipe failed!");
        return 1;
    }

    printf("program started\n");
    pid_fils=fork();
    if(pid_fils==0)
    {
        pid_pfils=fork();
        if(pid_pfils==0)
        {
            //action3
            printf("I am the grandson\n");
            close(fd[0]);//close read side
            dup2(fd[1],1);//connect write with stdout
            close(fd[1]);//close write side
            execlp("ls","ls",(char*)0);
            //execvp("ls",argv3);
            return 0;/*actions grandson*/
        }
        else
        {
            //action2
            printf("I am the son\n");
            wait();
            printf("son, wait ok\n");
            >close(fd[1]);  //close read side
            >dup2(fd[0],0); //connect write with stdin
            >close(fd[0]);  //close read side

            ///////pipe2////
           > close(fd2[0]);  //close read side
            >dup2(fd2[1],1); //connect write with stdout/*it stops here -can't display "ok!"*/
            printf("ok!\n");    
            >close(fd2[1]);  //close write side

            execlp("wc","wc",(char*)0);
            printf("error exec returned!\n");    
            return 0;
        }
    }
    else
    {
        ///action1
        printf("I am the parent\n");
        wait();
        printf("parent,wait ok\n");
        close(fd2[1]);  //close write side, 
        dup2(fd2[0],0); //connect read with stdin
        close(fd2[0]);  //close read side
        execlp("wc","wc",(char*)0);
        return 0;/*the parent*/
    }
    return 1;
}

Make sure you close all unused descriptors. 确保关闭所有未使用的描述符。 In your case, the easiest solution is to move the creation of pipe(fd) into the first if block (in the first sub-process). 在您的情况下,最简单的解决方案是将pipe(fd)的创建移到第一个if块中(在第一个子过程中)。 The problem is that as long as any process could possibly write to the pipe, the reader won't get EOF and so won't terminate. 问题在于,只要任何进程都可以写入管道,读取器就不会获得EOF,因此也不会终止。

if(pipe(fd2)==-1)
{
    printf("pipe failed!");
    return 1;
}

printf("program started\n");
pid_fils=fork();
if(pid_fils==0)
{
    if(pipe(fd)==-1)
    {
        printf("pipe failed!");
        return 1;
    }
    pid_pfils=fork();

I should also mention that you may want to reconsider the wait calls. 我还应该提到,您可能需要重新考虑等待电话。 Not sure what you are intending to do with them but you don't want the "ls" process to block on output because the reader hasn't been started yet. 不确定您打算对它们做什么,但是您不希望“ ls”过程阻塞输出,因为尚未启动阅读器。

dup2(fd2[1],1);

Above line will first close the file at descriptor 1 and then duplicate the decriptor from fd2[1] into 1. 上一行将首先关闭描述符1处的文件,然后将解密器从fd2 [1]复制到1。

1 is stdout. 1是标准输出。 Meaning that call closed stdout. 表示该调用关闭了stdout。

printf prints to stdout, meaning printf prints to 1 which is now assigned to the pipe fd2 printf打印到stdout,这意味着printf打印到1,现在分配给管道fd2

So your ok went into the pipe and not on the screen. 因此,您可以进入管道,而不是在屏幕上。

try 尝试

        //action2
        printf("I am the son\n");
        wait();
        printf("son, wait ok\n");
        close(fd[1]);  //close read side
        dup2(fd[0],0); //connect write with stdin
        close(fd[0]);  //close read side

        ///////pipe2////
        int my_terminal_out = dup(1);
        close(fd2[0]);  //close read side
        dup2(fd2[1],1); //connect write with stdout/*it stops here -can't display "ok!"*/
        fprintf(my_terminal_out, "ok!\n");    
        close(fd2[1]);  //close write side

Not tested. 未经测试。 Also you should test the rest of your code for similar missteps. 同样,您应该测试代码的其余部分是否存在类似的错误操作。

+What DrC said. + DrC怎么说。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM