Unix链管道延迟

时间:2014-11-03 04:16:37

标签: c linux unix pipe

我正在尝试为3个进程和当前程序创建一个管道链,以便:

1 - 执行P1并将P1的输出发送到P2的输入

3 - 将P2的输出发送到P3的输入

4 - 在stdout中显示P3的输出

5 - 将当前/主要/驱动程序的标准输入传递给P3的输入

我正在使用2个管道。对于任务#5,主程序从stdin读取并写入P3读取的管道。

我设法使进程相互通信。但是,我注意到在P1写入和P2在其STDIN上检测到写入之间存在很大的延迟,即P1在P2检测到写入之前可能已写入数百次并且在开始时错过了许多P1写入。我已通过打印消息确认P2实际上是按时启动的,但是,它没有及时检测/读取输入(这是一个Python脚本循环:“for sys.stdin中的行:”)

这是我的代码:

int pipe1[2];
int pipe2[2];
if (pipe(pipe1) < 0 || pipe(pipe2) < 0  )
{
    perror("Error: pipe");
}   


pid_t procIDC = fork();
if (procIDC == 0)
{       
    dup2(pipe2[0], 0);
    execv("procC", argv);           
}   
else
{       
    pid_t procIDB ;
    procIDB = fork();   

    if (procIDB == 0)
    {       
        dup2( pipe1[0], 0);  
        dup2( pipe2[1], 1);


        if (execl("/usr/bin/python", "/usr/bin/python", "./test.py", (char *)NULL) < 0)
        {
            perror("execl"); return 0;
        }
    }
    else
    {           
        pid_t procIDA = fork(); 
        if (procIDA ==0)
        {       
            dup2( pipe1[1], 1);
            execv("proc1", argv);       
        }   
        else
        {                   
            dup2( pipe2[1], 1);

            //print any input so it sends to p3
            ssize_t read;   
            char *inputLine = NULL;
            size_t len = 0;        
            while ((read = getline(&inputLine, &len, stdin)) != -1) 
            {
                printf(inputLine);
            }               
        }
    }

2 个答案:

答案 0 :(得分:2)

  

我注意到P1写入和P2在STDIN上检测到写入之间存在很大的延迟

是。你的问题可能是“为什么会有延迟”?

答案:stdio(大多数程序使用)在检测到输出进入管道时使用全缓冲输出

要防止缓冲,请使用fflushsetvbuf

一些额外的阅读here

  

实际上,fflush显然是在写作程序中完成的

您没有向我们展示其中包含fflush的写作程序。如果你有,我们可以指出你的错误(fflush 帮助,如果做得正确的话)。

无论如何,一种看待正在发生的事情的方法是运行strace -p <pid-of-writer>,并在编写器实际执行write(2)系统调用后立即观察 ,读者得到它的输入。这将证明它实际上是在作者中缓冲导致延迟。

此:

  

setbuf(stdout, NULL);

不会禁用缓冲。您确实需要致电setvbuf(或fflush)。

答案 1 :(得分:0)

P2中的STDIN有输入缓冲