【发布时间】:2019-07-03 11:05:49
【问题描述】:
在下面的小代码示例中,我不明白,当一个线程开始增加计数器时,该线程会将计数器地址写入内核之间共享的缓存中,并使计数器锁定在缓存中,直到该线程已经完成了计数器的写入,但是如果另一个尝试在前一个线程读写修改之间给这个计数器添加+1,他会看到缓存中的数据被锁定,然后呢?第二个线程会休眠还是等到缓存中的计数器解锁..?
如果线程休眠,我看不到原子和互斥锁对于小尺寸数据的好处:
// this_thread::yield example
#include <iostream> // std::cout
#include <thread> // std::thread, std::this_thread::yield
#include <atomic> // std::atomic
std::atomic<bool> ready (false);
std::atomic<int> counter (0);
void count1m(int id) {
while (!ready) { // wait until main() sets ready...
std::this_thread::yield();
}
for (volatile int i=0; i<10000; ++i) {
counter +=1;}
}
int main ()
{
std::thread threads[10];
std::cout << "race of 10 threads that count to 1 million:\n";
for (int i=0; i<10; ++i) threads[i]=std::thread(count1m,i);
ready = true; // go!
for (auto& th : threads) th.join();
std::cout << counter;
}
【问题讨论】:
-
很确定你不需要
volatile int i=0。int i = 0就足够了。 -
它不是真正的“锁”,核心只是同步缓存行(如果使用缓存)。是的,只要是缓存未命中,核心就会等待缓存更新。用于同步缓存/内存的策略取决于 cpu 架构,在这里写下来有点宽泛。
-
但是当没有“锁”的线程想要更新计数器时会发生什么?他是在睡觉还是别的什么?
-
@BenzaitSofiane 它停止了。从字面上看,只是停止内核,直到可以检索到缓存行。
-
我想我忘记了什么,因为我真的不明白这是什么意思:线程停止核心?
标签: c++ multithreading atomic lock-free