【问题标题】:C standard I/O vs UNIX I/O basicsC 标准 I/O 与 UNIX I/O 基础
【发布时间】:2012-01-20 12:51:18
【问题描述】:

这是我的一个非常基本的问题。在我教授的演讲幻灯片中,有一个我不太明白的例子。

她写道:

printf("u"); 
write(STDOUT_FILENO, "m", 1); 
printf("d\n");

...她说这段代码的输出是:

我不明白。所以如果有人明白为什么会发生这种情况,请向我解释。

参考这个问题:

http://lagoon.cs.umd.edu/216/Lectures/lect17.pdf

(在倒数第二张幻灯片页面中。)

【问题讨论】:

    标签: c linux unix io buffer


    【解决方案1】:

    write 是一个系统调用——它由用户模式(运行像您这样的程序)和操作系统内核(当字节写入文件时处理实际写入磁盘的操作)之间的接口实现。

    printf 是一个 C 标准库函数——它由加载到用户模式程序中的库代码实现。

    默认情况下,C 标准库输出函数会缓冲它们的输出,直到到达行尾。当缓冲区已满或以换行符终止时,通过从库实现中调用 write 将其写入文件。

    因此,通过printf 的输出不会立即发送到操作系统write。在您的示例中,您缓冲字母“u”,然后立即写入字母“m”,然后将“d\n”附加到缓冲区,标准库调用write(STDOUT_FILENO, "ud\n");

    【讨论】:

      【解决方案2】:

      默认情况下,stdout行缓冲;在遇到换行符(或缓冲区填满)之前,它不会刷新到输出。

      所以"u" 位于缓冲区中,直到收到"d\n"。但是write 绕过了这个缓冲区。

      【讨论】:

      • 我不会说写“颠覆”任何东西。缓冲区完好无损且工作正常。更准确地说,write 是一个系统调用,而 printf 是一个库函数。
      • stdout 默认为 not 行缓冲。 如果 stdout 与 tty 相关联,则默认情况下它是行缓冲的。如果 stdout 是常规文件或管道(或实际上不是 tty 的任何东西),默认情况下它将被块缓冲。
      • @WilliamPursell:从技术上讲,如果stdout可以确定不是交互式设备,它可能是块缓冲而不是行缓冲。
      猜你喜欢
      • 2015-05-24
      • 1970-01-01
      • 2016-02-20
      • 1970-01-01
      • 1970-01-01
      • 2012-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多