目录
1、std::adopt_lock
Value used as possible argument to the constructor of unique_lock or lock_guard.
unique_lock objects constructed with adopt_lock do not lock the mutex object on construction, assuming instead that it is already locked by the current thread.
The value is a compile-time constant that carries no state, and is merely used to disambiguate between constructor signatures.
adopt_lock_t is an empty class.
2、std::defer_lock
Value used as possible argument to unique_lock's constructor.
unique_lock objects constructed with defer_lock do not lock the mutex object automatically on construction, initializing them as not owning a lock.
The value is a compile-time constant that carries no state, and is merely used to disambiguate between constructor signatures.
defer_lock_t is an empty class.
3、std::try_to_lock
Value used as possible argument to unique_lock's constructor.
unique_lock objects constructed with try_to_lock attempt to lock the mutex object by calling its try_lock member instead of its lock member.
The value is a compile-time constant that carries no state, and is merely used to disambiguate between constructor signatures.
4、compare
std::defer_lock 、 std::try_to_lock 和 std::adopt_lock 分别是空结构体标签类型 std::defer_lock_t 、 std::try_to_lock_t 和 std::adopt_lock_t 的实例。
它们用于为 std::lock_guard 、 std::unique_lock 及 std::shared_lock 指定锁定策
类型 | 效果 |
defer_lock_t | 不获得互斥的所有权 |
try_to_lock_t | 尝试获得互斥的所有权而不阻塞 |
adopt_lock_t | 假设调用方线程已拥有互斥的所有权 |
example
#include <iostream>
#include <mutex>
#include <thread>
struct bank_account {
explicit bank_account(int balance) : balance(balance) {}
int balance;
std::mutex m;
};
void transfer(bank_account &from, bank_account &to, int amount)
{
// 锁定两个互斥而不死锁
std::lock(from.m, to.m);
// 保证二个已锁定互斥在作用域结尾解锁
std::lock_guard<std::mutex> lock1(from.m, std::adopt_lock);
std::lock_guard<std::mutex> lock2(to.m, std::adopt_lock);
// 等价方法:
// std::unique_lock<std::mutex> lock1(from.m, std::defer_lock);
// std::unique_lock<std::mutex> lock2(to.m, std::defer_lock);
// std::lock(lock1, lock2);
from.balance -= amount;
to.balance += amount;
}
int main()
{
bank_account my_account(100);
bank_account your_account(50);
std::thread t1(transfer, std::ref(my_account), std::ref(your_account), 10);
std::thread t2(transfer, std::ref(your_account), std::ref(my_account), 5);
t1.join();
t2.join();
std::cout<<"my balance"<<my_account.balance<<std::endl;
std::cout<<"your balance"<<your_account.balance<<std::endl;
}
output:
std::defer_lock作为第二参数来传递,表示该互斥元在构造时保持未被锁定。这个锁就可以在这之后通过在std::unique_lock对象(不是互斥元)来上调用lock。