C++中的锁🔒
C++中的互斥锁
C++14中有五种互斥锁:
std::mutex
std::timed_mutex
std::recursive_mutex
std::recursive_timed_mutex
std::shared_timed_mutex
其中,名称中带有“timed”的变体和不带“timed”的变体相同,只是锁定操作可以指定超时,以限制最大等待时间。如果没有指定超时,那么锁操作将阻塞,直到可以获取所为止–如果持有锁🔒的线程从不释放它,则可能永远阻塞。
std::mutex
和std::timed_mutex
只是普通的单所有者互斥锁。
std::recursive_mutex
和std::recursive_timed_mutex
是递归互斥锁,因此单个线程可以持有多个锁。
std::shared_timed_mutex
是一个读/写互斥锁。
C++锁定对象
为了配合各种互斥锁类型,C++标准为持有锁的对象定义了三组类模板。分别为:
std::lock_guard<>
std::unique_lock<>
std::shared_lock<>
对于基本操作,它们都在构造函数中获取锁,并在析构函数中释放。但是如果出于需要,它们可以以更复杂的方式使用。
std::lock_guard<>
是最简单的类型,只在单个块中的关键部分持有锁:
|
|
std::unique_lock<>
类似,只不过它可以从函数返回而不释放锁,并且可以在析构函数之前释放锁:
|
|
std::shared_lock<>
和std::unique_lock<>
几乎一样,只是它需要mutex上的共享锁。
如果使用std::shared_timed_mutex
作为mutex,那么可以用std::lock_guard<std::shared_timed_mutex>
或者std::unique_lock<std::shared_timed_mutex>
获得排它锁(X),使用std::shared_lock<std::shared_timed_mutex>
获取共享锁(S)。
|
|
C++中的信号量Semaphores
C++标准中并没有定义信号量类型。因此我们可以根据自己的需要使用原子计数器,互斥锁,或者条件变量实现我们自己的信号量。但无论如何,大多数情况下信号量的使用可以用互斥锁/条件变量替换。
在某些情况下,如果确实需要使用信号量,使用mutex和conditional variable会增加开销,C++标准中没有解决方案。