write 和 printf 乱序输出

write and printf out of order output

在编写 c 程序时,我遇到了一个令人费解的 printf 和 write 行为。看起来 write 在某些情况下会在 printf 之前调用,即使它在代码中是在它之后(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.

write 没有缓冲 printf 是。每当您使用 write 时,它都会到达控制台 - 但是当它在这里到达 \n 时会输出 printf,因为缓冲区会被刷新。

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

您可以在 printf 调用后立即使用 fflush(stdout) 刷新输出。 (Steve Summit 对此发表了评论)

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

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


另外如 zwol 所述,您可以在对标准 I/O 函数进行任何其他调用之前使用此方法关闭 stdout 的行缓冲。

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

除了提到的在每次输出操作后使用fflush()之外,您还可以使用

stdout unbuffered
setvbuf(stdout, NULL, _IONBF, 0);

这样,printfputsputchar、...的所有输出都会按 write 输出的顺序出现(无需撒上周围有很多 fflush()。