【问题标题】:Disable buffering for stdin and stdout using setvbuf()使用 setvbuf() 禁用标准输入和标准输出的缓冲
【发布时间】:2013-10-14 17:18:22
【问题描述】:

当我阅读setvbuf() 的用法时,我遇到了_IONBF(无缓冲)模式。所以我很好奇如果我尝试禁用缓冲,stdin 和 stdout 会受到怎样的影响。下面是一个示例代码:

代码:

#include <stdio.h>

int main(void)
{

   int num;
   char a;
   setvbuf(stdin, NULL, _IONBF, 0); //turn off buffering
   scanf("%d", &num);
   a = getchar();
   printf("%d %c\n", num , a);

       return 0;
}

问题:

1.) 从上面的代码中,即使我没有包含setvbuf(),我给程序的示例输入(123a 等)也会产生相同的输出。

2.) 我知道缓冲区是一个中间存储,可以在其中填充一大块数据,并且当缓冲区已满或给出换行符时,所有这些数据都将发送到输入或输出流。

3.) 那么禁用缓冲区有什么影响呢?是在性能方面吗?

【问题讨论】:

    标签: c file-io stream buffer stdio


    【解决方案1】:

    它部分是性能,部分是对流库函数(fread、fgets、fprintf 等)如何与设备/文件的实际 I/O 相关的控制。

    例如,默认情况下,流输出到字符设备(例如您的终端)是行缓冲的。这样的效果就是如下代码,

    printf("start ");
    sleep(10);
    printf("stop\n");
    

    将等待 10 秒,然后打印 start stop[NL]。第一个打印被缓冲,因为没有新行来刷新缓冲区。要打印start,然后休眠10 秒,您可以在sleep 调用之前添加fflush 调用,或者使用setvbuf 关闭stdout 的缓冲。

    默认情况下,流输出到块设备或磁盘文件是完全缓冲的。这意味着缓冲区不会刷新,直到您溢出缓冲区或执行fflush。这可能是文件的问题,例如,如果您想使用tail -f 实时监控输出。如果您知道可以完成此监视,则可以将流切换到行缓冲,以便每次打印换行时,将缓冲区刷新到文件中。这将以增加开销为代价,因为在打印新行时会多次写入磁盘块。 (注意:此开销取决于文件系统的挂载方式。固定驱动器(挂载的回写缓存)在操作系统缓冲区写入磁盘时的开销会更少,而可移动驱动器挂载的写入方式则更少。在后者中在这种情况下,如果驱动器在未卸载的情况下被移除,操作系统将尝试执行部分写入以提高避免数据丢失的机会。)

    【讨论】:

      猜你喜欢
      • 2012-05-02
      • 2014-12-07
      • 1970-01-01
      • 2013-11-28
      • 1970-01-01
      • 1970-01-01
      • 2011-05-03
      • 2017-05-16
      • 2013-10-27
      相关资源
      最近更新 更多