Implementing a lock

Implementing a lock

本文关键字:lock Implementing      更新时间:2023-10-16

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

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

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

资源的用户调用 lock() ,如果isLocked为 true,则lock()返回 false,资源的用户必须等待或执行其他操作。如果isLocked为 false,则lock() isLocked设置为 true,并返回 true。然后,调用方可以对资源执行任何他想要的操作。之后,他调用资源unlock(),将isLocked设置为 false。

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

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

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

#include <atomic>
std::atomic<bool> isLocked;
bool lock() { return !isLocked.exchange(true); }
void unlock() { isLocked = false; }

这里的关键是原子交换和(隐式)原子存储,它们生成特殊的硬件指令并且始终是无种族的,并且你不能用普通变量"伪造"。

"

原子"表示操作不能中断。 也就是说,您可以确定该操作的语义是相同的,而不管其他线程/进程的行为如何。 你是对的,你的lock()通话中的某些东西可能必须是原子的。 大多数体系结构都提供了一些有用的说明,并保证了原子行为 - 您可能还会发现一些基于这些操作构建的库,以便在您正在编程的更高层为您提供更大的灵活性。

一点也不罕见。 它被称为争用条件,是多线程代码中许多(如果不是大多数)错误的原因。

C++标准实际上没有任何线程/原子性等概念,1 因此您需要依赖操作系统(或通过 Boost)提供的同步原语。


1. C++11 不再如此。