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 不再如此。
相关文章:
- Implementing WM_QUERYENDSESSION
- 尝试构建"lock-free"数据结构C++
- OpenGL Implementing MultiPass
- 为什么 c++11 std::lock 和 std::scoped_lock 至少需要 2 个参数?
- 为什么"weak.lock()"返回"nullptr" "auto weak=std::make_shared<int>(42);"的定义?
- DRD 报告"conflicting load" std::mutex::lock 上的错误
- 在 std::tie 中使用 std::weak_ptr::lock()
- Implementing winapi(SendInput) with dart:ffi
- std::lock_guard 怎么可能比 std::mutex::lock() 更快?
- std::mutex::lock() 产生奇怪(和不必要的)ASM 代码
- "lock cmpxchg"如何在装配中工作?
- Implementing Active Directory with C++ Builder
- std::lock 仍然导致死锁
- 在任何地方对C++中所有并行线程中的所有锁定和解锁实例使用相同的 std::mutex 和 lock 对象
- 我们是否需要对多线程 x32 系统使用 lock 来读取或写入 uint32_t 变量
- 使用Mutex,lock_guard,在课堂中正确地lock
- Implementing is_constexpr_copiable
- 当我调用lock()时,为什么std :: mutex会引发异常
- mutex.lock vs unique_lock
- Implementing a lock