简体   繁体   English

为什么将 fprintf 与 stdout 或 stderr 一起使用时,output 顺序与调用顺序不同?

[英]Why is the output order different from the call order when using fprintf with stdout or stderr?

My environment is Debian GNU/Linux 11.我的环境是 Debian GNU/Linux 11。

The fprintf function with param stdout or stderr gives unexpected output order.带有参数stdoutstderrfprintf function 给出了意外的 output 订单。

int main() {
    std::cout << "Hello, World!" << std::endl;
    fprintf(stderr, "22222\n");
    fprintf(stdout, "111\n");
    printf("3333 \n");
    printf("44444 \n");
    return 0;
}

I've run this many times and got many different results:我已经运行了很多次并得到了许多不同的结果:

//①
22222
Hello, World!
111
3333 
44444

//②
Hello, World!
111
3333 
44444 
22222

What's the reason?什么原因? Or, I want to understand the phenomenon, what knowledge do I need?或者,我想了解现象,需要什么知识?

On my understanding, the output log should like this:据我了解,output 日志应该是这样的:

//③
Hello, World!
22222
111
3333 
44444 

About the two output logs of ①/②, I don't understand.关于①/②的两条output日志,看不懂。

I think log ③ is right, but it does not appear, that makes me wonder.我认为日志③是对的,但它没有出现,这让我感到奇怪。

The output is never like ② because output to stderr isn't buffered so 22222 will be flushed immediately and would be before any other numbers. output永远不会像②,因为output 到stderr没有被缓冲,所以22222将立即被刷新,并且会在任何其他数字之前。 Output to stdout may be line-buffered (default on Linux) or full-buffered (default on Windows) Output 到stdout可以是行缓冲的(Linux 上的默认值)或全缓冲的(Windows 上的默认值)

The output shouldn't be like ① either because you're already flushing with std::endl in the first line , hence Hello, World! output 也不应该像①,因为你已经在第一行用std::endl刷新了,因此Hello, World! would be printed first.将首先打印。 That's why never use std::endl unless you really know what it's doing.这就是为什么永远不要使用std::endl ,除非你真的知道它在做什么。 Always use std::cout << "Hello, World;\n";始终使用std::cout << "Hello, World;\n"; . . See "std::endl" vs "\n"参见“std::endl”与“\n”

③ should be the correct output because on Linux it'll flush on every statement, and on Windows the final 3 writes to stdout are flushed at once at the end ③ 应该是正确的 output 因为在 Linux 上它会在每条语句上刷新,在 Windows 上,最后 3 次写入到stdout结束时立即刷新

Hello, World!
22222
111
3333 
44444

If there are any differences then there are some issues with your stdlib如果有任何差异,那么您的 stdlib 存在一些问题

By default the legacy and C++ streams are also synchronized so it's possible to mix both types of streams with some performance penalty.默认情况下 ,legacy 和 C++ 流也是同步的,因此可以混合两种类型的流,但会带来一些性能损失。 You can disable it like this你可以像这样禁用它

std::ios::sync_with_stdio(false);

to get better performance but now the Hello, World!为了获得更好的性能,但现在是Hello, World! string can be printed anywhere字符串可以在任何地方打印

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM