gpt4 book ai didi

c++ - 为什么 std::cout 在线程中被抢占但 printf 却没有?

转载 作者:太空狗 更新时间:2023-10-29 20:24:42 27 4
gpt4 key购买 nike

我开始学习 C++11 标准中的线程,我正在尝试一个非常基本的程序,它创建 10 个线程,加入它们,然后退出。在线程函数中,我尝试打印出我在其中创建线程的 for 循环的索引,如下所示:

std::vector<std::thread> threads;
for(int i = 0; i < 10; i++)
{
threads.push_back(std::thread([i](){ printf("Thread #%d\n", i); }));
}

这会产生一个并发程序所期望的输出,线程乱序执行:

Thread #0
Thread #2
Thread #1
Thread #3
Thread #4
Thread #5
Thread #6
Thread #7
Thread #8
Thread #9

但是当我尝试使用 std::coutstd::endl 做同样的事情时,我得到了这个:

Thread #0
Thread #Thread #2
Thread #3
Thread #9
1
Thread #8
Thread #4
Thread #5
Thread #7
Thread #6

为什么 std::cout 会发生这种情况,而 printf 不会发生这种情况?

最佳答案

您没有显示您的 std::cout 代码。

threads.push_back(std::thread([i](){ printf("Thread #%d\n", i); }));

但如果我假设您将代码更改为:

threads.push_back(std::thread([i](){ std::cout << "Thread #" << i << std::endl; }));

两者有很大的不同:

printf版本只有一次调用打印库。:

printf("Thread #%d\n", i);

operator<<对打印库有三个不同的调用

operator<<(std::cout, "Thread #");
operator<<(std::cout, i);
operator<<(std::cout, std::endl);

// note for the pedantic the use of functions here is for illustration purposes.

假设打印库内部有某种锁 printf version 将为您提供每个线程的一行。而 operator<<版本可能会在调用之间被抢占。

即使有内部锁,我也不会赌任何版本。打印部分可能刚好足够短,在那里观察到中断的可能性很小,因此您可能还没有观察到它。

尝试:

threads.push_back(std::thread([i]()
{ std::stringstream msg;
msg << "Thread #" << i << "\n";
std::cout << msg.rdbuf();
}));

关于c++ - 为什么 std::cout 在线程中被抢占但 printf 却没有?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26703548/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com