如何修复TSAN报出的“解锁未锁定互斥量”警告?
修复ThreadSanitizer提示的“unlock of an unlocked mutex”错误
问题分析
你的代码功能正常,但ThreadSanitizer(TSAN)报出解锁未锁定互斥量的警告,核心问题出在以下两点:
冗余锁对象引发TSAN跟踪误判
函数开头的std::unique_lock<std::timed_mutex> lock(_processMutex, std::try_to_lock);虽未持有锁,但TSAN在跟踪锁状态时,可能对该对象的析构逻辑产生误判,触发警告。共享变量缺乏原子性保护
_cancellationRequested被多线程读写却未使用原子类型,存在数据竞争,这可能间接干扰TSAN对互斥量操作的正常跟踪。
修复方案
- 替换第一个
unique_lock为直接调用互斥量的try_lock()方法,手动解锁,消除冗余锁对象。 - 将
_cancellationRequested声明为std::atomic<bool>,确保多线程读写的原子性,消除数据竞争。 - 保持
_cancelled的访问始终在互斥量保护下,保证线程安全。
修改后的代码
#include <atomic> #include <mutex> #include <chrono> class Sender { private: std::timed_mutex _processMutex; std::atomic<bool> _cancellationRequested{false}; // 改为原子类型 bool _cancelled{false}; // 其他成员变量... public: bool CancelRequest(); // 其他成员函数... }; bool Sender::CancelRequest() { // 直接调用try_lock判断是否有正在执行的请求 if (_processMutex.try_lock()) { // 拿到锁说明无活跃请求,解锁后返回 _processMutex.unlock(); return false; } // 设置取消标记(原子操作,无需加锁) _cancellationRequested = true; // 等待获取锁,确认取消状态 std::unique_lock<std::timed_mutex> timedLock(_processMutex, std::chrono::seconds(30)); if (!timedLock.owns_lock()) { // 超时未拿到锁,取消失败 return false; } // 持有锁时读取_cancelled,保证线程安全 return _cancelled; }
额外注意事项
- 工作线程检测
_cancellationRequested时,因它是原子变量,无需加锁即可安全读取。 - 工作线程完成取消操作后,需在持有
_processMutex的情况下设置_cancelled = true,确保CancelRequest线程能读取到正确状态。
内容的提问来源于stack exchange,提问作者Sujith Gunawardhane
相关产品推荐
相关产品推荐

