一 类型
1. std::defer_lock_t 、 std::try_to_lock_t 和 std::adopt_lock_t 是用于为 std::lock_guard(C++11) 、 std::scoped_lock(C++14) 、 std::unique_lock(C++11) 和 std::shared_lock(C++17) 指定锁定策略的空结构体标签类型。 2. 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 假设调用方线程已拥有互斥的所有权
三 构造函数
1. lock_guard
explicit lock_guard( mutex_type& m ); (1)(C++11 起) lock_guard( mutex_type& m, std::adopt_lock_t t ); (2)(C++11 起) lock_guard( const lock_guard& ) = delete; (3)(C++11 起)2. unique_lock
unique_lock() noexcept;(1) (since C++11) unique_lock( unique_lock&& other ) noexcept;(2)(since C++11) explicit unique_lock( mutex_type& m );(3)(since C++11) unique_lock( mutex_type& m, std::defer_lock_t t ) noexcept;(4)(since C++11) unique_lock( mutex_type& m, std::try_to_lock_t t );(5)(since C++11) unique_lock( mutex_type& m, std::adopt_lock_t t );(6)(since C++11) template< class Rep, class Period > unique_lock( mutex_type& m,const std::chrono::duration<Rep,Period>& timeout_duration );(7)(since C++11) template< class Clock, class Duration > unique_lock( mutex_type& m,const std::chrono::time_point<Clock,Duration>& timeout_time );(8)(since C++11)3. scoped_lock
explicit scoped_lock( MutexTypes&... m ); (1)(C++17 起) scoped_lock( std::adopt_lock_t, MutexTypes&... m ); (2)(C++17 起) scoped_lock( const scoped_lock& ) = delete; (3)(C++17 起)4. shared_lock
shared_lock() noexcept;(1)(C++14 起) shared_lock( shared_lock&& other ) noexcept;(2)(C++14 起) explicit shared_lock( mutex_type& m );(3)(C++14 起) shared_lock( mutex_type& m, std::defer_lock_t t ) noexcept;(4)(C++14 起) shared_lock( mutex_type& m, std::try_to_lock_t t );(5)(C++14 起) shared_lock( mutex_type& m, std::adopt_lock_t t );(6)(C++14 起) template< class Rep, class Period > shared_lock( mutex_type& m, const std::chrono::duration<Rep,Period>& timeout_duration );(7)(C++14 起) template< class Clock, class Duration > shared_lock( mutex_type& m, const std::chrono::time_point<Clock,Duration>& timeout_time );(8)(C++14 起)四 Demo
#include <chrono> #include <functional> #include <iostream> #include <mutex> #include <string> #include <thread> #include <vector> struct Employee { Employee(std::string id) : id(id) {} std::string id; std::vector<std::string> lunch_partners; std::mutex m; std::string output() const { std::string ret = "Employee " + id + " has lunch partners: "; for (const auto& partner : lunch_partners) ret += partner + " "; return ret; } }; void send_mail(Employee&, Employee&) { // simulate a time-consuming messaging operation std::this_thread::sleep_for(std::chrono::seconds(1)); } void assign_lunch_partner(Employee& e1, Employee& e2) { static std::mutex io_mutex; { std::lock_guard<std::mutex> lk(io_mutex); std::cout << e1.id << " and " << e2.id << " are waiting for locks" << std::endl; } { std::lock(e1.m, e2.m); std::lock_guard<std::mutex> lk1(e1.m, std::adopt_lock); std::lock_guard<std::mutex> lk2(e2.m, std::adopt_lock); // 等效代码1 // std::unique_lock<std::mutex> lk1(e1.m, std::defer_lock); // std::unique_lock<std::mutex> lk2(e2.m, std::defer_lock); // std::lock(lk1, lk2); // 等效代码2 // std::scoped_lock lock(e1.m, e2.m); { std::lock_guard<std::mutex> lk(io_mutex); std::cout << e1.id << " and " << e2.id << " got locks" << std::endl; } e1.lunch_partners.push_back(e2.id); e2.lunch_partners.push_back(e1.id); } send_mail(e1, e2); send_mail(e2, e1); } int main() { Employee alice("alice"), bob("bob"), christina("christina"), dave("dave"); // assign in parallel threads because mailing users about lunch assignments // takes a long time std::vector<std::thread> threads; threads.emplace_back(assign_lunch_partner, std::ref(alice), std::ref(bob)); threads.emplace_back(assign_lunch_partner, std::ref(christina), std::ref(bob)); threads.emplace_back(assign_lunch_partner, std::ref(christina), std::ref(alice)); threads.emplace_back(assign_lunch_partner, std::ref(dave), std::ref(bob)); for (auto& thread : threads) thread.join(); std::cout << alice.output() << '\n' << bob.output() << '\n' << christina.output() << '\n' << dave.output() << '\n'; std::cin.get(); return 0; }结果:
alice and bob are waiting for locks christina and bob are waiting for locks alice and bob got locks christina and alice are waiting for locks christina and alice got locks dave and bob are waiting for locks christina and bob got locks dave and bob got locks Employee alice has lunch partners: bob christina Employee bob has lunch partners: alice christina dave Employee christina has lunch partners: alice bob Employee dave has lunch partners: bob
五 参考
cppreference