为什么将 fprintf 与 stdout 或 stderr 一起使用时,输出顺序与调用顺序不同?
Why is the output order different from the call order when using fprintf with stdout or stderr?
我的环境是 Debian GNU/Linux11.
带参数 stdout
或 stderr
的 fprintf
函数给出了意外的输出顺序。
int main() {
std::cout << "Hello, World!" << std::endl;
fprintf(stderr, "22222\n");
fprintf(stdout, "111\n");
printf("3333 \n");
printf("44444 \n");
return 0;
}
我已经 运行 了这么多次,得到了很多不同的结果:
//①
22222
Hello, World!
111
3333
44444
//②
Hello, World!
111
3333
44444
22222
这是什么原因?
或者,我想了解现象,需要什么知识?
据我了解,输出日志应该是这样的:
//③
Hello, World!
22222
111
3333
44444
关于①/②的两条输出日志,我没看懂
我认为日志③是对的,但是没有出现,这让我很奇怪。
输出是 never 像 ② 因为 output to stderr
isn't buffered 所以 22222
将被立即刷新并且会在任何其他数字之前。 stdout
的输出可能是 行缓冲 (Linux 的默认值)或 全缓冲的 (Windows)
输出也不应该像①,因为you're already flushing with std::endl
in the first line, hence Hello, World!
would be printed first. That's why never use std::endl
unless you really know what it's doing. Always use std::cout << "Hello, World!\n";
. See "std::endl" vs "\n"
③ 应该是正确的输出,因为在 Linux 上它会在每个语句上刷新,而在 Windows 上最后 3 次写入 stdout
在最后一次刷新
Hello, World!
22222
111
3333
44444
如果有任何差异,则说明您的标准库存在一些问题
默认情况下 the legacy and C++ streams are also synchronized 因此可以将两种类型的流混合使用,但会降低一些性能。你可以像这样禁用它
std::ios::sync_with_stdio(false);
以获得更好的性能,但现在 Hello, World!
字符串可以在任何地方打印
我的环境是 Debian GNU/Linux11.
带参数 stdout
或 stderr
的 fprintf
函数给出了意外的输出顺序。
int main() {
std::cout << "Hello, World!" << std::endl;
fprintf(stderr, "22222\n");
fprintf(stdout, "111\n");
printf("3333 \n");
printf("44444 \n");
return 0;
}
我已经 运行 了这么多次,得到了很多不同的结果:
//①
22222
Hello, World!
111
3333
44444
//②
Hello, World!
111
3333
44444
22222
这是什么原因? 或者,我想了解现象,需要什么知识?
据我了解,输出日志应该是这样的:
//③
Hello, World!
22222
111
3333
44444
关于①/②的两条输出日志,我没看懂
我认为日志③是对的,但是没有出现,这让我很奇怪。
输出是 never 像 ② 因为 output to stderr
isn't buffered 所以 22222
将被立即刷新并且会在任何其他数字之前。 stdout
的输出可能是 行缓冲 (Linux 的默认值)或 全缓冲的 (Windows)
输出也不应该像①,因为you're already flushing with std::endl
in the first line, hence Hello, World!
would be printed first. That's why never use std::endl
unless you really know what it's doing. Always use std::cout << "Hello, World!\n";
. See "std::endl" vs "\n"
③ 应该是正确的输出,因为在 Linux 上它会在每个语句上刷新,而在 Windows 上最后 3 次写入 stdout
在最后一次刷新
Hello, World!
22222
111
3333
44444
如果有任何差异,则说明您的标准库存在一些问题
默认情况下 the legacy and C++ streams are also synchronized 因此可以将两种类型的流混合使用,但会降低一些性能。你可以像这样禁用它
std::ios::sync_with_stdio(false);
以获得更好的性能,但现在 Hello, World!
字符串可以在任何地方打印