std::defer_lock_t, std::try_to_lock_t, std::adopt_lock_t

< cpp‎ | thread
 
 
线程支持库
线程
(C++11)
(C++20)
(C++20)
this_thread 命名空间
(C++11)
(C++11)
(C++11)
互斥
(C++11)
通用锁管理
(C++11)
defer_lock_ttry_to_lock_tadopt_lock_t
(C++11)(C++11)(C++11)
(C++11)
(C++11)
(C++11)(C++11)(C++11)
(C++11)
(C++11)
条件变量
(C++11)
信号量
闩与屏障
(C++20)
(C++20)
future
(C++11)
(C++11)
(C++11)
(C++11)
 
定义于头文件 <mutex>
struct defer_lock_t { explicit defer_lock_t() = default; };

struct try_to_lock_t { explicit try_to_lock_t() = default; };

struct adopt_lock_t { explicit adopt_lock_t() = default; };
(C++11 起)

std::defer_lock_tstd::try_to_lock_tstd::adopt_lock_t 是用于为 std::lock_guardstd::scoped_lockstd::unique_lockstd::shared_lock 指定锁定策略的空类标签类型。

 
类型 效果
defer_lock_t 不获得互斥的所有权
try_to_lock_t 尝试获得互斥的所有权而不阻塞
adopt_lock_t 假设调用方线程已拥有互斥的所有权

示例

#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();
}


缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

DR 应用于 出版时的行为 正确行为
LWG 2510 C++11 默认构造函数为非 explicit ,能导致歧义 使之为 explicit

参阅

用于指定锁定策略的标签常量
(常量)
构造 lock_guard ,可选地锁定给定的互斥
(std::lock_guard<Mutex> 的公开成员函数)
构造 unique_lock ,可选地锁定提供的互斥
(std::unique_lock<Mutex> 的公开成员函数)