实现锁定

new*_*mer 4 c++ multithreading locking

我试图了解锁是如何工作的.

假设我想在C++中实现一个非常简单的锁

class Resource{
    public:
    bool lock();
    void unlock();
    ... methods to change/read the Resource ...

    private:
    bool isLocked;
}
Run Code Online (Sandbox Code Playgroud)

Resource调用的用户lock(),如果isLocked为true,则lock()返回false,并且Resource的用户必须等待或执行其他操作.如果isLocked为false,则lock()设置isLocked为true,并返回true.然后调用者可以对资源做任何他想做的事情.他之后调用unlock()资源设置isLocked为false.

但是,如果资源的两个用户lock()在同一时间呼叫怎么办?这种情况很少发生吗?我认为更正式地说,这涉及使lock()操作"原子化",尽管我不确定这个词是什么意思.

Ker*_* SB 5

使用旧的标准C++,您无法实现自己的锁,因为锁变量本身处于数据竞争中.

C++ 11和C11添加原子变量,您可以将其用于此目的; 例如在C++中:

#include <atomic>

std::atomic<bool> isLocked;

bool lock() { return !isLocked.exchange(true); }

void unlock() { isLocked = false; }
Run Code Online (Sandbox Code Playgroud)

这里的关键是原子交换和(隐式)原子存储,它们生成特殊的硬件指令并且总是无竞争,并且你不能用普通变量"假".


Car*_*rum 3

“原子”意味着操作不能被中断。也就是说,您可以确保无论其他线程/进程的行为如何,该操作的语义都是相同的。你是对的,你的lock()通话中的某些内容可能必须是原子的。大多数架构都提供了一些有用的指令,并保证了原子行为 - 您可能还会发现一些基于这些操作构建的库,以便在您正在编程的更高层上提供更大的灵活性。