write和printf乱序输出

时间:2018-01-06 15:40:46

标签: c printf output order-of-execution

在编写c程序时,我遇到了printf和write的令人费解的行为。似乎在某些情况下,在printf之前调用write,即使它在代码之后(printf是异步的吗?)。此外,如果printf中有两行,则之后的输出似乎插入它们之间。我的问题是导致这种行为的原因,我怎么知道什么时候会发生?那么其他输出函数(例如puts) - 我可以在文档中查找一些内容,以了解它们与其他函数的行为方式。示例代码:

#include <unistd.h>
#include <stdio.h>

int main(void)
{
    write(STDOUT_FILENO, "1.", 2);
    printf("2.");
    write(STDOUT_FILENO, "3.", 2);
    printf("4.\n5.");
    printf("6.");
    write(STDOUT_FILENO, "7.", 2);
    return 0;
}

输出:

1.3.2.4.
7.5.6.

2 个答案:

答案 0 :(得分:4)

write未缓存printf。每当你使用write它进入控制台时 - printf在这里得到\n时输出,因为那时刷新了缓冲区。

这就是为什么1.3.之后你会看到2.4.

您可以在fflush(stdout)来电后立即使用printf刷新输出。 (Steve Summit评论此内容)

您可能想知道\n之后没有其他printf那么为什么这些字符会被刷新?

在程序终止时,还会刷新输出缓冲区。这就是导致其余printf输出出现的原因。 setvbuf()函数只能在打开流之后以及对其执行任何其他操作之前使用。

同样如zwol所述,在对标准I / O函数进行任何其他调用之前,您可以使用此变换stdout的行缓冲区。

setvbuf(stdout, 0, _IONBF, 0)
                   ^^^
                   causes input/output to be unbuffered

答案 1 :(得分:2)

除了在每次输出操作后提到synchronized("") { if (count > 0) { System.out.println("Current value is: " + count--); } } 的使用外,您还可以使用

使fflush() 无缓冲
stdout

这样,setvbuf(stdout, NULL, _IONBF, 0); printfputs,......的所有输出都会按照putchar输出顺序显示(无需花费很多fflush()s around)。