C++的锁你知道几种?
这些都是抽象的锁类型,哪个语言都可以有……
C++标准库里有的:
std::mutex
(C++11),普通互斥锁,可以阻塞式等锁(lock()
)也可以非阻塞式上锁(try_lock()
)std::timed_mutex
(C++11),互斥锁的加时版本,如果在一段时间内(try_lock_for()
)或是在某个时间之前(try_lock_until()
)获取锁成功则成功上锁std::recursive_mutex
(C++11),递归互斥锁,在互斥锁的基础上允许持有锁的线程多次通过lock()
或者try_lock()
获取锁,而std::mutex
的拥有者不能继续请求上锁std::recursive_timed_mutex
(C++11),递归锁的加时版本std::shared_mutex
(C++17),共享互斥锁,允许多个线程共享锁(lock_shared()
系列),但只有一个线程能够持有互斥锁(lock()
系列),也就是一般所说的读写锁std::shared_timed_mutex
(C++14),共享互斥锁的加时版本。该版本先于不加时的,因为当时赶着把共享互斥锁加进标准来不及了
RAII式锁管理器:std::lock_guard<Mutex>
(C++11),最基础的管理器,只能自动上锁,退出作用域自动解锁,提前解锁都做不到std::unique_lock<Mutex>
(C++11),独享所有权的锁管理器,除基础RAII功能之外还能移交所有权(此时不解锁),(解锁后)上锁和(提前)解锁std::scoped_lock<Mutexes...>
(C++17),同时获取多个锁的锁管理器,获取过程是原子性的,要么同时获取要么什么都没有,避免一个个获取锁的时候发生死锁std::shared_lock<SharedMutex>
(C++14),配合共享锁使用的锁管理器
原子变量:std::atomic<T>
(C++11),就是……原子变量。但不保证原子性不是由锁来实现的std::atomic_flag
(C++11),原子性的标记变量,保证其原子性的实现是无锁的
条件变量:std::condition_variable
(C++11),需要std::unique_lock
来使用std::condition_variable_any
(C++11),不限于std::unique_lock
标准库并没有自旋锁std::spin_lock
。自旋锁是忙等的,可以用std::atomic_flag
来实现:
#include <atomic> #include <iostream> std::atomic_flag lock = ATOMIC_FLAG_INIT; // 这是个标准库里的宏 void spin_lock_output(int n) { // 上锁 while(lock.test_and_set(std::memory_order_acquire)) ; // 忙等自旋 std::cout << "output from thread " << n << std::endl; // 解锁 lock.clear(std::memory_order_release); }