这个打印订单有什么问题

sas*_*har 1 c pipe

看看这段代码:

 #include<stdio.h>
 #include <unistd.h>
    int main()
    {
            int pipefd[2],n;
            char buf[100];
            if(pipe(pipefd)<0)
                    printf("Pipe error");
            printf("\nRead fd:%d write fd:%d\n",pipefd[0],pipefd[1]);
            if(write(pipefd[1],"Hello Dude!\n",12)!=12)
                    printf("Write error");
            if((n=read(pipefd[0],buf,sizeof(buf)))<=0)
                    printf("Read error");
            write(1,buf,n);
            return 0;
    }
Run Code Online (Sandbox Code Playgroud)

我希望printf在从管道中读取Hello Dude之前打印Read fd并写入fd.但情况并非如此......请看这里.当我在我们的大学计算机实验室尝试相同的程序时,我的输出是

Read fd:3 write fd:4
Hello Dude!
Run Code Online (Sandbox Code Playgroud)

我们的朋友也很少观察到,更改printf语句以包含更多数量的\n字符会改变输出顺序......例如.. printf("\nRead fd:%d\n write fd:%d\n",pipefd[0],pipefd[1]);意味着打印了读取fd然后打印Hello Dude!了写入fd 的消息.这是什么行为?注意:Out lab使用我们运行终端的linux服务器,但我不记得编译器版本.

pax*_*blo 5

这是因为printf标准输出是缓冲的,但是write标准输出文件描述符不是.

这意味着行为可以根据您的缓冲类型而改变.在C中,如果可以确定标准输出连接到交互设备,则标准输出是缓冲的.否则它是完全缓冲的(请参阅此处以了解为何如此).

行缓冲意味着它会在看到换行符时刷新到文件描述符.完全缓冲意味着它只会在缓冲区填充时刷新(例如,4K值的数据),或者当流关闭时(或当您关闭时fflush).

当您以交互方式运行时,刷新发生在write因为printf遇到\n并自动刷新之前.

然而,当你运行它,否则(如通过重定向输出到文件或在线编译器/执行它可能会做,以捕获演示数据同样的事情),刷新发生write(因为printf不是每次冲洗后,每一行).

实际上,根据以下程序,您不需要那里的所有管道内容来查看此操作:

    #include <stdio.h>
    #include <unistd.h>
    int main (void) {
        printf ("Hello\n");
        write (1, "Goodbye\n", 8);
        return 0;
    }
Run Code Online (Sandbox Code Playgroud)

当我执行时myprog ; echo === ; myprog >myprog.out ; cat myprog.out,我得到:

Hello
Goodbye
===
Goodbye
Hello
Run Code Online (Sandbox Code Playgroud)

你可以看到不同类型的缓冲产生的差异.

如果您想要线路缓冲而不管重定向,您可以尝试:

setvbuf (stdin, NULL, _IOLBF, BUFSIZ);
Run Code Online (Sandbox Code Playgroud)

在你的程序的早期 - 它的实现定义了一个实现是否支持这个,所以它可能没有效果,但我没有看到很多它不起作用.