实现锁定

时间:2012-04-07 22:03:23

标签: c++ multithreading locking

我正在努力了解锁是如何工作的。

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

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

    private:
    bool isLocked;
}

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

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

3 个答案:

答案 0 :(得分:5)

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

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

#include <atomic>

std::atomic<bool> isLocked;

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

void unlock() { isLocked = false; }

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

答案 1 :(得分:3)

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

答案 2 :(得分:1)

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

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

<小时/> <子> 1。对于C ++ 11,情况不再如此。