锁类 stdtry 的策略是锁定 stdadopt 锁定 stddefer 锁
创建 std::unique_lock 时,有三种不同的锁定策略可供选择:std::try_to_lock
,std::defer_lock
和 std::adopt_lock
std::try_to_lock
允许在不阻塞的情况下尝试锁定:
{
std::atomic_int temp {0};
std::mutex _mutex;
std::thread t( [&](){
while( temp!= -1){
std::this_thread::sleep_for(std::chrono::seconds(5));
std::unique_lock<std::mutex> lock( _mutex, std::try_to_lock);
if(lock.owns_lock()){
//do something
temp=0;
}
}
});
while ( true )
{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::unique_lock<std::mutex> lock( _mutex, std::try_to_lock);
if(lock.owns_lock()){
if (temp < INT_MAX){
++temp;
}
std::cout << temp << std::endl;
}
}
}
std::defer_lock
允许在不获取锁的情况下创建锁结构。当锁定多个互斥锁时,如果两个函数调用者同时尝试获取锁,则会有一个死锁机会窗口:
{
std::unique_lock<std::mutex> lock1(_mutex1, std::defer_lock);
std::unique_lock<std::mutex> lock2(_mutex2, std::defer_lock);
lock1.lock()
lock2.lock(); // deadlock here
std::cout << "Locked! << std::endl;
//...
}
使用以下代码,无论函数中发生什么,都会以适当的顺序获取和释放锁:
{
std::unique_lock<std::mutex> lock1(_mutex1, std::defer_lock);
std::unique_lock<std::mutex> lock2(_mutex2, std::defer_lock);
std::lock(lock1,lock2); // no deadlock possible
std::cout << "Locked! << std::endl;
//...
}
- 如果调用线程当前拥有锁,则
std::adopt_lock
不会尝试第二次锁定。
{
std::unique_lock<std::mutex> lock1(_mutex1, std::adopt_lock);
std::unique_lock<std::mutex> lock2(_mutex2, std::adopt_lock);
std::cout << "Locked! << std::endl;
//...
}
要记住的是 std::adopt_lock 不能代替递归互斥锁用法。当锁超出范围时,互斥锁被释放。