std::unique_lock<>灵活加锁
参考博客
相较于std::lock_guard,std::unqiue_lock并不与互斥量的数据类型直接相关,因此使用起来更加灵活
它在构造时可以传入额外的参数,如std::adopt_lock与std::defer_lock等
std::unqiue_lock的时空间性能均劣于std::lock_guard,这也是它为灵活性付出的代价
std::unqiue_lock内存在某种标志用于表征其实例是否拥有特定的互斥量,显然,这些标志需要占据空间,并且标志的检查与更新也需要耗费时间
std::adopt_lock参数
- std::adopt_lock参数表示互斥量已经被lock,不需要再重复lock
- 该互斥量之前必须已经lock,才可以使用该参数
std::try_to_lock参数
- 可以避免一些不必要的等待,会判断当前mutex能否被lock,如果不能被lock,可以先去执行其他代码
- 这个和adopt不同,不需要自己提前加锁
举个例子来说就是如果有一个线程被lock,而且执行时间很长,那么另一个线程一般会被阻塞在那里,反而会造成时间的浪费。那么使用了try_to_lock后,如果被锁住了,它不会在那里阻塞等待,它可以先去执行其他没有被锁的代码
#include <iostream>
#include <mutex>
std::mutex mlock;
void work1(int& s) {
for (int i = 1; i <= 5000; i++) {
std::unique_lock<std::mutex> munique(mlock, std::try_to_lock);
if (munique.owns_lock() == true) {
s += i;
}
else {
// 执行一些没有共享内存的代码
}
}
}
void work2(int& s) {
for (int i = 5001; i <= 10000; i++) {
std::unique_lock<std::mutex> munique(mlock, std::try_to_lock);
if (munique.owns_lock() == true) {
s += i;
}
else {
// 执行一些没有共享内存的代码
}
}
}
int main()
{
int ans = 0;
std::thread t1(work1, std::ref(ans));
std