同一线程多次锁定std::mutex致未定义行为,recursive_mutex是否可行?
用
std::recursive_mutex解决同一线程重复加锁的问题 这确实是std::recursive_mutex的典型适用场景之一,咱们一步步拆解来看:
问题根源
你当前使用的std::mutex是**非递归(不可重入)**的互斥锁。当同一个线程已经持有这把锁的情况下,再次调用lock(),线程会进入阻塞状态——它会等待自己释放锁,这就形成了死锁,也就是你提到的“未定义行为”(在多数标准库实现里,这种情况直接表现为死锁)。
std::recursive_mutex的解决方案
std::recursive_mutex正是为这种“同一线程需要多次获取同一锁”的场景设计的:
- 它内部会维护一个锁计数,同一线程每调用一次
lock(),计数加1;每调用一次unlock(),计数减1。 - 只有当计数回到0时,锁才会真正被释放,其他线程才有机会获取这把锁。
你只需要修改Object类里的互斥锁类型即可,接口完全兼容现有代码:
#include <mutex> class Object { std::recursive_mutex lck; public: void lock() { lck.lock(); } void unlock() { lck.unlock(); } void doSomething() {} };
额外注意事项
- 不要滥用递归锁:如果可以通过重构代码避免同一线程多次加锁(比如调整嵌套调用的逻辑,或者合并锁的范围),优先选择重构。递归锁比普通
std::mutex有轻微的性能开销,而且过度依赖它可能隐藏代码中不必要的嵌套锁逻辑。 - 严格保证锁的配对:每一次
lock()必须对应一次unlock(),如果计数不匹配(比如多解锁或少解锁),会导致锁状态异常,其他线程可能永远无法获取锁。
内容的提问来源于stack exchange,提问作者Martin Perry
相关产品推荐
相关产品推荐

