C++11 defer_lock try_to_lock adopt_lock

一 类型

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值