【问题标题】:Flush kernel buffers for stdout刷新标准输出的内核缓冲区
【发布时间】:2014-10-08 12:41:48
【问题描述】:

我正在学习内核缓冲区并了解当我们写入文件时,即使在刷新后也不一定会立即进入文件;它被放入内核缓冲区,稍后将被刷新。显然我们可以调用fsync() 来刷新内核缓冲区,所以我做了如下实验:

/* This works fine, nRet is 0 */
FILE* file = fopen("MyFile", "w");
fprintf(file, "1234");
fflush(file);
int nRet = fsync(fileno(file));

/* This doesn't work, nRet is -1 and errno is 22 (Invalid argument)*/
fprintf(stdout, "Output to standard out");
fflush(stdout);
int p = fileno(stdout);
nRet = fsync(p);

我完全清楚我们并不严格需要刷新内核缓冲区,但这纯粹是一种学习体验。

我找不到任何说明fsync() 不适用于标准输出的内容;当然无论如何它都必须这样做,因为我们可能希望为控制台提供超快速更新,在这种情况下,如果我们没有使用 O_SYNC 打开控制台的输出,这将是必需的...

有人能解释一下发生了什么吗?提前致谢。

【问题讨论】:

  • fflush 用于流,fsync 用于文件。
  • 不知道你在这里得到了什么。 fflush 刷新用户空间缓冲区,而fsync 刷新内核缓冲区。被刷新的东西可以是流或文件...

标签: c++ linux-kernel


【解决方案1】:

documentation 说:

EINVAL
fd 绑定到不支持的特殊文件 同步。

控制台设备不是普通文件,没有内核缓冲区;任何写入都由控制台驱动程序立即处理。 如果不是这种情况,这样的代码将不起作用:

printf("Please enter something: ");
scanf(...);

【讨论】:

  • 嗯,好的。但是很多次我已经调用了返回的printf(),但我仍然可以在控制台上看到输出......我也没有得到你的示例显示的内容。它们是在那里使用的两个不同的流,所以我不明白你所说的“不起作用”是什么意思......你能详细说明一下吗?
  • 如果控制台不同步,则不会显示提示。
  • 提示是指光标,还是正在打印的消息?即便如此,我之前肯定打印过的东西在调试器中运行时并没有立即显示出来,所以我不确定这是正确的。 (我并没有不尊重的意思,非常感谢您的帮助,只是我真的很想了解这一点。)
  • 控制台没有内核缓冲区。
  • 1.设备(即不是文件)总是在收到数据后立即处理数据。 2. 是的。 3. 是的。
猜你喜欢
  • 2020-09-02
  • 1970-01-01
  • 1970-01-01
  • 2014-10-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-02
  • 2018-04-17
  • 1970-01-01
相关资源
最近更新 更多