一、lock.trylock带参数
lock.trylock方法是用来获取锁的,比较常用并且非阻塞。如果锁已经被其他线程获取,那么方法直接返回false。如果锁没有被其他线程获取,那么方法获取锁并且直接返回true。
在C++11中,lock.trylock方法可以传递一个std::adopt_lock_t类型的参数,通过这个参数告知方法获取锁并且托管给std::unique_lock对象。下面是一个典型的例子:
std::mutex m; std::unique_lock lock(m, std::try_to_lock); if (lock.owns_lock()) { // ... }
在上面的例子中,unique_lock对象会尝试获取锁,如果获取成功,那么该对象会托管std::mutex对象并且进行使用。
二、lock.trylock三个参数
在C++11中,lock.trylock方法也可以传递三个参数。下面是三个参数的含义:
- lock.trylock(m):尝试获取锁,如果锁已经被其他线程获取,那么方法直接返回false。
- lock.trylock(m, std::defer_lock):创建unique_lock对象但不获取锁。
- lock.trylock(m, std::try_to_lock):尝试获取锁,如果锁已经被其他线程获取,那么方法直接返回false。
在以上三个参数中,std::defer_lock是最常用的。下面是一个典型的例子:
std::mutex m; std::unique_lock lock(m, std::defer_lock); if (lock.try_lock()) { // ... }
在上面的例子中,unique_lock对象不会尝试获取锁。当unique_lock对象调用try_lock方法时,对象会尝试获取锁。
三、lock.trylock后再lock会报错吗
在C++11和C++17中,lock.trylock获取锁后,如果锁已经被其他线程获取,那么方法会直接返回false而不是阻塞调用线程。因此,在获取锁前没有任何问题。
每个线程在获取锁后,需要在规定的时候释放锁。在释放锁前,不能再次锁定相同的锁。下面是一个例子:
std::mutex m; std::unique_lock lock(m); if (lock.try_lock()) { // ... lock.unlock(); } lock.lock(); //会报错
在上面的例子中,unique_lock对象首先尝试获取锁并且成功,然后执行一些代码,最后释放锁。但是在释放锁后,该线程又再次尝试获取相同的锁。这时候会产生死锁。
原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/270453.html