Pei*_*pei 0 c++ atomic stdatomic
我谈到的例子是cppreference.com 上的这个例子。代码片段粘贴在下面。
int main(){
const std::size_t ThreadNumber = 5;
const int Sum = 5;
std::atomic<int> atom{0};
std::atomic<int> counter{0};
// lambda as thread proc
auto lambda = [&](const int id){
for (int next = 0; next < Sum;){
// each thread is writing a value from its own knowledge
const int current = atom.exchange(next);
counter++;
// sync writing to prevent from interrupting by other threads
std::osyncstream(std::cout)
<< '#' << id << " (" << std::this_thread::get_id()
<< ") wrote " << next << " replacing the old value "
<< current << '\n';
next = std::max(current, next) + 1;
}
};
std::vector<std::thread> v;
for (std::size_t i = 0; i < ThreadNumber; ++i){
v.emplace_back(lambda, i);
}
for (auto& tr : v){
tr.join();
}
std::cout << ThreadNumber << " threads adding 0 to "
<< Sum << " takes total "
<< counter << " times\n";
}
Run Code Online (Sandbox Code Playgroud)
对我来说, 的值为counter25,因为有 5 个线程,每个线程循环 5 次。然而,显示的输出是 16。我自己也运行了它,可能的值有所不同,但它永远不会是 25。
为什么计数器的打印值实际上更小?
考虑一种可能的执行方式:
假设其中一个线程在其他线程开始之前完成循环。
这给了你atom == 4。下一个进入循环的线程将获得current == 4并将在第一次迭代后退出循环。
这样,第二个线程就会递增current一次,而不是像您期望的那样递增 5 次。