我实现了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_weaktrue true。这样就成功了,您刚刚获得了另一个线程持有的锁。

解:
确保在每个unlatched之前将false设置回compare_exchange_weak,例如:

while(!latch.compare_exchange_weak(unlatched, true, std::memory_order_acquire)) {
    unlatched = false;
}

07-24 22:35