[英]Implementing a lock
我试图了解锁是如何工作的。
假设我想在 C++ 中实现一个非常简单的锁
class Resource{
public:
bool lock();
void unlock();
... methods to change/read the Resource ...
private:
bool isLocked;
}
Resource 的用户调用lock()
,如果isLocked
为真,则lock()
返回 false,并且 Resource 的用户必须等待或做其他事情。 如果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)提供的同步原语。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.