我实现了SpinLock类,如下
struct Node {
int number;
std::atomic_bool latch;
void add() {
lock();
number++;
unlock();
}
void lock() {
bool unlatched = false;
while(!latch.compare_exchange_weak(unlatched, true, std::memory_order_acquire));
}
void unlock() {
latch.store(false , std::memory_order_release);
}
};
我实现了上面的类,并创建了两个线程,每个线程分别调用Node类的同一实例的add()方法1000万次。
不幸的是,结果不是2000万。
我在这里想念什么?
最佳答案
问题在于,一旦失败,compare_exchange_weak
就会更新unlatched
变量。从compare_exchange_weak
的文档中:
也就是说,在第一个失败的compare_exchange_weak
之后,unlatched
将更新为true
,因此下一个循环迭代将尝试使用compare_exchange_weak
来true
true
。这样就成功了,您刚刚获得了另一个线程持有的锁。
解:
确保在每个unlatched
之前将false
设置回compare_exchange_weak
,例如:
while(!latch.compare_exchange_weak(unlatched, true, std::memory_order_acquire)) {
unlatched = false;
}