0

除了手动调用flush之外,cout或者STDOUT(printf)会flush的条件是什么?

退出当前范围或当前功能?是定时的吗?缓冲区满时刷新(缓冲区有多大)?

4

1 回答 1

2

对于<stdio.h>流,您可以使用设置缓冲模式setvbuf()。它采用三种缓冲模式:

  1. _IOFBF:当缓冲区已满或明确请求刷新时,将刷新缓冲区。
  2. _IOLBF:当找到换行符、缓冲区已满或请求刷新时刷新缓冲区。
  3. _IONBF:流是无缓冲的,即,一旦可用就发送输出。

我有印象,默认设置stdout_IOLBF,因为stderr它是_IONBF,对于其他流它是_IOFBF。但是,查看 C 标准,我没有找到任何关于任何 C 流的默认值的指示。

对于标准的 C++ 流对象,没有等价于_IOLBF: 如果您想要使用行缓冲区std::endl,则最好使用'\n'std::flush. 但是,有一些设置std::ostream

  1. 您通常可以使用buf.pubsetbuf(0, 0)将流转换为无缓冲。由于用户可以实现流缓冲区,因此不能保证设置缓冲区的相应调用会被兑现。
  2. 您可以设置std::ios_base::unitbuf在每次 [正确实施] 输出操作后刷新流的原因。默认情况下std::ios_base::unitbuf仅设置为std::cerr.
  3. std::ostream当缓冲区已满或显式请求时刷新缓冲区的正常设置,不幸的是,std::endl在许多情况下会显式请求刷新缓冲区(在许多情况下会导致性能问题,因为它往往被用作它的'\n'代理不是)。
  4. 一个有趣的是in.tie()输出缓冲区到输入流的能力:如果in.tie()包含指向std::ostream此输出流的指针,则将在尝试读取之前刷新in(当然,假设正确实现了输入运算符)。默认情况下,std::couttie()d 到std::cin
  5. 差点忘记了一个重要的问题:如果std::ios_base::sync_with_stdio()没有使用false标准 C++ 流(std::cin、和它们的对应物)调用 if ,则std::cout可能完全没有缓冲!使用标准 C 和 C++ 流的默认设置,可以混合使用。然而,由于 C 库通常忽略 C++ 库,这意味着 C++ 标准流对象不能进行任何缓冲。使用是标准 C++ 流对象主要性能问题!std::cerrstd::clogwchar_tstd::ios_base::sync_with_stdio(true)std::sync_with_stdio(true)

在 C 和 C++ 中,您都不能真正控制缓冲区的大小:允许忽略设置非零缓冲区的请求,通常会被忽略。也就是说,流几乎会在一些随机的地方被刷新。

于 2013-11-10T20:24:52.243 回答