【C++】互斥锁-②

std::recursive_mutex(递归锁)

1. 类原型:

Defined   in header 
class recursive_mutex;

 recursive_mutex。在此期间,线程可能会对lock或try_lock进行额外的调用。当线程进行匹配数量的解锁调用时,所有权期结束。

当一个线程拥有一个recursive_mutex时,所有其他线程如果试图声明recursive_mutex的所有权,将会阻塞(对于锁的调用)或接收一个错误的返回值(对于try_lock)。一个recursive_mutex被锁定的最大次数是未知的,但是达到这个数字之后,调用lock将抛出std::system_error,调用try_lock将返回false。如果一个recursive_mutex被销毁,而它仍然被某些线程拥有,那么程序的行为是未定义的。recursive_mutex类满足Mutex和StandardLayoutType的所有要求。

2. 当一个线程拥有recursive_mutex时,所有其他线程去获取recursive_mutex递归锁时,将会阻塞(对于锁的调用)或接收一个错误的返回值(对于try_lock)。

1. 代码实现

#include <iostream>
#include <thread>
#include <mutex>

class X
{
  std::recursive_mutex m;
  std::string shared;

public:
  void fun1()
  {
    std::lock_guard<std::recursive_mutex> lk(m);
    shared = "fun1";
    std::cout << "ID:" << std::this_thread::get_id() << " in fun1, shared is " << shared << std::endl;
  }
  void fun2()
  {
    std::lock_guard<std::recursive_mutex> lk(m);
    shared = "fun2";
    std::cout << "ID:" << std::this_thread::get_id() << " in fun2, shared is " << shared << std::endl;
    fun1();
    std::cout << "ID:" << std::this_thread::get_id() << " back in fun2, shared is " << shared << std::endl;
  };
};

int main()
{
  X x;
  std::thread t1(&X::fun2, &x);
  std::thread t2(&X::fun2, &x);
  t1.join();
  t2.join();
}

输出:

 

std::scoped_lock 是 C++17 引入的一个轻量级锁守卫类,用于一次性锁住一个或多个互斥量(std::mutex、std::recursive_mutex 等),并在作用域结束时自动释放锁,从而实现 RAII(资源获取即初始化)风格的互斥控制。

 
基本特性
  • 构造时自动加锁
  • 析构时自动解锁
  • 支持同时锁住多个 mutex,且避免死锁(通过内部排序)
  • 不支持延迟加锁或 try_lock(如 unique_lock)

示例一:锁一个 mutex

#include <iostream>
#include <mutex>
#include <thread>

std::mutex mtx;

void print_message(const std::string& msg) {
    std::scoped_lock lock(mtx); // 自动加锁
    std::cout << msg << '\n';   // 安全访问共享资源
} // 作用域结束自动解锁

int main() {
    std::thread t1(print_message, "Hello from t1");
    std::thread t2(print_message, "Hello from t2");

    t1.join();
    t2.join();
}
 
 
示例二:同时锁住多个 mutex(避免死锁)
#include <iostream>
#include <mutex>
#include <thread>

std::mutex m1, m2;

void task() {
    std::scoped_lock lock(m1, m2); // 一次性安全加锁多个 mutex,避免死锁
    std::cout << "Both mutexes locked.\n";
}

int main() {
    std::thread t1(task);
    std::thread t2(task);

    t1.join();
    t2.join();
}

 

参考资料

1. C++ 官方文档

1.

 

posted @ 2022-04-16 13:18  苏格拉底的落泪  阅读(503)  评论(0)    收藏  举报