C++ std::recursive_mutex 递归锁

在多线程编程中,锁是保证数据同步与线程安全的核心机制。但当一个线程多次获取同一把锁时,普通互斥锁会导致死锁。递归锁(Recursive Mutex)允许同一个线程多次获取同一把锁而不会产生死锁。本文将深入探讨 C++ 中递归锁的原理、使用场景及注意事项。

1. 锁的用法

C++11 标准库提供了std::recursive_mutex作为递归锁的实现,其使用方式与普通互斥锁类似,主要接口包括:

  • lock():获取锁(同一线程可多次调用)
  • unlock():释放锁(需与 lock 次数匹配)
  • try_lock():尝试获取锁(成功返回 true,失败返回 false)

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


std::recursive_mutex mtx;

void demo()
{
	// 递归锁允许获得锁的线程多次调用 lock 函数
	mtx.lock();
	mtx.lock();

	// 调用多少次 lock,就需要调用几次 unlock,否则会发生死锁
	mtx.unlock();
	mtx.unlock();

	if (mtx.try_lock())
	{
		std::cout << "count: " << mtx._Mtx_storage._Count << std::endl;
		mtx.unlock();
		std::cout << "count: " << mtx._Mtx_storage._Count << std::endl;
	}
}


int main()
{
	demo();
	return 0;
}

2. 锁的原理

std::mutex 和 std::recursive_mutex 两个锁都是继承基类锁基类 _Mutex_base,但是传递给父类的锁类型参数不同:

class recursive_mutex : public _Mutex_base {
public:
    recursive_mutex() noexcept
        : _Mutex_base(_Mtx_recursive) {}

    bool try_lock() noexcept {
        return _Mutex_base::try_lock() && _Verify_ownership_levels();
    }

    recursive_mutex(const recursive_mutex&)            = delete;
    recursive_mutex& operator=(const recursive_mutex&) = delete;
};

递归锁在内部维护一个计数变量 _Count。当线程第一次获取锁时, _Count 被设置为 1,其他线程此时会被阻塞。如果同一线程再次对该锁加锁, _Count 会递增,表示该线程多次持有该锁。每次解锁 unlock 操作会使 _Count 递减,当 _Count 归零时,锁才会被真正释放,此时其他等待的线程才能继续获取该锁。

注意:下面代码运行需要把 recursive_mutex 的成员修改为 public 权限

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

std::recursive_mutex mtx;

void print_count()
{
	std::cout << "count: " << mtx._Mtx_storage._Count 
		<< " thread ID: " << mtx._Mtx_storage._Thread_id << std::endl;
}

void demo()
{
	mtx.lock();
	print_count();

	mtx.lock();
	print_count();

	mtx.unlock();
	print_count();

	mtx.unlock();
	print_count();

	if (mtx.try_lock())
	{
		print_count();
		mtx.unlock();
		print_count();
	}
}


int main()
{
	demo();
	return 0;
}
count: 1 thread ID: 6156
count: 2 thread ID: 6156
count: 1 thread ID: 6156
count: 0 thread ID: -1
count: 1 thread ID: 6156
count: 0 thread ID: -1
未经允许不得转载:一亩三分地 » C++ std::recursive_mutex 递归锁
评论 (0)

5 + 6 =