版权声明:所有的博客都是博主的个人笔记。。。。。 https://blog.csdn.net/qq_35976351/article/details/84139547
std::lock_guard
这是最简单的一个管理锁的对象。只有构造和析构函数,在构造的时候加锁,析构的时候解锁,解锁后就不能使用该对象再加锁了。可以避免使用std::mutex
时忘记解锁的情况,同时可以方便处理异常。
简单的实例:
#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
#include <stdexcept>
std::mutex mtx;
void print_even(int n) {
if(n % 2 == 0) {
std::cout << n << " is even\n";
} else {
throw std::logic_error("not even\n");
}
}
void print_thread_id(int id) {
try {
// 在这里,try块是单独一个部分,离开块之后,锁就自动析构了
std::lock_guard<std::mutex>lck(mtx);
print_even(id);
} catch(std::logic_error&) {
std::cout << "[exception caught]\n";
}
}
int main() {
// 创建线程组
std::vector<std::thread>threads;
for(int i = 0; i < 10; ++i) {
threads.emplace_back(std::thread(print_thread_id, i + 1));
}
// 所有线程等待归并
for(auto& th : threads) {
th.join();
}
return 0;
}
/*
输出结果:
[exception caught]
2 is even
[exception caught]
4 is even
[exception caught]
6 is even
[exception caught]
8 is even
[exception caught]
10 is even
*/
std::unique_lock
拥有std::lock_guard
所有的功能,但是更加灵活,也有更多的接口;时间和空间要求也更高了。
给出常用的5个构造函数:
unique_lock() noexcept; // (1)
explicit unique_lock (mutex_type& m); // (2)
unique_lock (mutex_type& m, try_to_lock_t tag); // (3)
unique_lock (mutex_type& m, defer_lock_t tag) noexcept; // (4)
unique_lock (mutex_type& m, adopt_lock_t tag); // (5)
- 仅仅定义一个对象,不管理任何锁对象
- 管理锁对象
m
,同时尝试调用m.lock()
进行加锁,如果别的unique_lock
已经管理了当前锁m
,那么当前线程阻塞。 - 管理锁对象
m
,如果上锁失败,线程不会阻塞 - 管理锁对象
m
,初始化的时候不会锁住m
- 管理锁对象
m
,而且m
应当是一个已经被当前线程锁住的Mutex对象
常用的成员函数:
try_lock
上锁成功返回true
,否则返回false
try_lock_for
,调用管理对象的try_lock_for
函数,成功返回true
,失败返回false
try_lock_until
,同try_lock_for
unlock
,调用管理对象的unlock
函数release
,返回管理锁的指针,并释放管理权owns_lock
,判断是否拥有了锁。