锁类 stdtry 的策略是锁定 stdadopt 锁定 stddefer 锁

创建 std::unique_lock 时,有三种不同的锁定策略可供选择:std::try_to_lockstd::defer_lockstd::adopt_lock

  1. 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;
        }
    }
}
  1. 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;
       //...
       
   }
  1. 如果调用线程当前拥有锁,则 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 不能代替递归互斥锁用法。当锁超出范围时,互斥锁被释放