【问题标题】:What is meant by stream buffering?流缓冲是什么意思?
【发布时间】:2014-06-11 11:57:45
【问题描述】:

我已经开始学习 C 编程,所以我是初学者,在学习标准文本流时,我想出了“stdout”流被缓冲而“stderr”流没有被缓冲,但我没有能够理解这一行。

我已经在这个论坛上阅读过关于“缓冲区”的内容,并且我喜欢糖果类比,但是当有人说:“这个流被缓冲而另一个没有被缓冲时,我无法弄清楚是什么意思。 "什么效果?

有什么区别?

更新:会影响处理速度吗?

【问题讨论】:

  • stdout 视为运输线卡车。你开始把箱子装进领头卡车。当卡车已满时有人按喇叭并说“Ship It!”时,您将其发送出去。卡车离开,下一辆卡车停在装卸码头,过程继续进行。现在将stderr 想象成一排自行车,每辆都有一个可以容纳一个 盒子的架子。每次您将一个箱子扔出去运送时,骑手拿走它,然后立即离开(因为只能拿一个)。这几乎概括了它。是的,您可以想象,一千辆自行车的效率远低于十辆卡车。
  • @WhozCraig,比一个答案,我会赞成。很好的比喻。
  • @WhozCraig 这是一个非常贴切和有用的类比,尤其是And yes, as you can imagine, a thousand bikes is far less efficient than ten trucks. 这个评论值得回答:)
  • @ajay 我真的很喜欢(并且点赞)你和 Paul 的回答。我特别喜欢您的回答中对 gcc 的三种缓冲区方法的摘要描述以及 Paul 的简洁性。我的评论更多的是尝试将代码与概念分离,并且由于我不清楚这就是 OP 正在寻找的东西,所以觉得它适合这里而不是那里。无论如何,谢谢你的道具!

标签: c stream buffer


【解决方案1】:

缓冲是在写入之前收集许多元素,或者在处理它们之前一次读取许多元素。网上有很多信息,例如this

和其他 SO 问题,例如 this

针对问题更新进行编辑:是的,它是出于性能原因而完成的。在任何情况下,从磁盘等写入和读取都会写入或读取大多数设备的某种“块”,这样做会产生相当大的开销。因此,批量处理这些操作可以带来巨大的性能差异

【讨论】:

  • 很高兴您添加了该编辑!这是我问题的最佳答案!谢谢。
【解决方案2】:

缓冲区是属于流的一块内存,用于临时保存流数据。当对文件进行第一次 I/O 操作时,会调用 malloc 并获取缓冲区。写入流的字符通常会累积在缓冲区中(在以块的形式传输到文件之前),而不是在应用程序输出它们时立即出现。类似地,流以块的形式而不是逐个字符地从主机环境中检索输入。这样做是为了提高效率,因为与内存操作相比,文件和控制台 I/O 速度较慢。

GCC 提供三种类型的缓冲 - 无缓冲、块缓冲和行缓冲。无缓冲意味着字符在写入后立即出现在目标文件中(对于输出流),或者从文件中逐个字符地读取输入,而不是读取块(对于输入流)。块缓冲意味着字符保存在缓冲区中并作为块写入或读取。行缓冲意味着字符仅保存到换行符写入缓冲区或从缓冲区读取。 stdinstdout 被块缓冲当且仅当它们可以确定不引用交互式设备,否则它们被行缓冲(对于任何流都是如此)。默认情况下,stderr 始终是无缓冲的。

标准库提供了改变流默认行为的函数。您可以使用fflush 强制将数据从输出流缓冲区中取出(fflush 对于输入流未定义)。您可以使用setbuf 函数使流无缓冲。

【讨论】:

    【解决方案3】:

    写入缓冲输出的程序可以在写入缓冲区所需的时间内执行输出,这通常非常快,与可能很慢的输出设备的速度无关。

    对于缓冲输出,信息是队列,一个单独的进程处理输出渲染。

    使用无缓冲输出,数据直接写入输出设备,因此以设备上的速度运行。这对于错误输出很重要,因为如果输出被缓冲,则进程可能在缓冲输出到达显示器之前失败 - 因此程序可能会在没有诊断输出的情况下终止。

    【讨论】:

      猜你喜欢
      • 2010-10-13
      • 2017-12-04
      • 2013-02-09
      • 2020-01-20
      • 2019-01-30
      • 1970-01-01
      • 2021-11-19
      • 1970-01-01
      • 2020-07-21
      相关资源
      最近更新 更多