c++oding="utf-8" ?>
try_lock 总是返回 false 通常是因为当前线程已持有该 std::mutex,而 std::mutex 不可重入,重复加锁会导致未定义行为;正确用法是在确定锁未被本线程持有时调用,或改用 std::recursive_mutex(但不支持非阻塞争抢),配合 std::unique_lock 时应使用 std::try_to_lock 构造并检查 owns_lock()。

try_lock 为什么总是返回 false?
多数时候 try_lock 返回 false 并不是函数坏了,而是你调用它时锁已经被当前线程持有了——std::mutex 不可重入,同一个线程重复调用 try_lock(或 lock)会引发未定义行为。C++ 标准明确要求:对已由当前线程锁定的 std::mutex 再次加锁是未定义的。
验证方式很简单:
std::mutex mtx; mtx.lock(); bool ok = mtx.try_lock(); // 此时 ok 必为 false,且后续行为不可靠
- 只在确定锁未被本线程持有时调用
try_lock - 若需可重入逻辑,改用
std::recursive_mutex,但它不提供try_lock的“非阻塞争抢”语义,仅支持同一线程多次 lock/unlock -
try_lock设计目标是跨线程竞争场景,不是线程内重入检查
try_lock 在 std::unique_lock 中怎么用才安全?
std::unique_lock 的构造函数支持延迟锁定,配合 std::defer_lock 和手动 try_lock() 是标准用法。直接传 std::try_to_lock 更简洁,且自动处理状态同步。
std::mutex mtx;
std::unique_lock<:mutex> lk(mtx, std::try_to_lock);
if (lk.owns_lock()) {
// 成功获取,可以安全操作临界区
} else {
// 未获取到,避免阻塞,做其他事(如重试、降级、返回)
}
</:mutex>
- 别写
std::unique_lock lk(mtx); lk.try_lock();—— 这会先尝试默认构造并隐式调用lock(),可能死锁或抛异常 -
std::try_to_lock是 tag type,仅用于构造时触发try_lock()调用,不是布尔值 - 构造后务必用
lk.owns_lock()判断结果,不能只看是否抛异常(try_lock本身不抛异常)
多个 mutex 的 try_lock 顺序错乱会导致死锁
用 std::try_lock(全局函数)同时尝试多个互斥量时,必须严格按固定顺序调用,否则仍可能死锁。该函数内部采用“试探-回退”策略,但前提是所有线程遵守相同顺序。
std::mutex mtx1, mtx2;
// ✅ 正确:统一约定 mtx1 先于 mtx2
auto result = std::try_lock(mtx1, mtx2);
if (result == -1) { // 全部成功
// 持有 mtx1 和 mtx2
} else {
// 至少一个失败,已自动释放所有已获取的锁
}
- 参数顺序即加锁顺序,所有线程必须一致(比如都用
mtx_a, mtx_b,绝不能有的用mtx_a, mtx_b,有的用mtx_b, mtx_a) - 返回值是首个失败锁的索引(0-based),-1 表示全部成功;失败时已自动 unlock 所有此前成功获取的锁
- 不要混用
std::try_lock和手写循环try_lock()—— 后者无法保证原子性回退,极易残留部分加锁状态
try_lock 性能开销比 lock 小,但不是零成本
try_lock 底层通常对应一条原子指令(如 x86 的 XCHG 或 CMPXCHG),比 lock 少了等待和调度开销,但仍有缓存行争抢和内存屏障代价。高频轮询 try_lock 可能导致 CPU 空转和伪共享问题。
- 避免在 tight loop 里无休止调用
try_lock,应加入退避(如std::this_thread::yield()或指数退避) - 在低竞争场景下,
try_lock+ 失败后 fallback 的模式比单纯lock更高效;高竞争时,频繁失败反而增加总开销 - 某些实现(如 libc++)对
try_lock做了轻量优化,但 glibc 的 pthread_mutex_trylock 仍涉及系统调用路径,不可假设恒定快速
真正 tricky 的地方在于:try_lock 的语义是“此刻是否能立即拿到锁”,它不承诺之后的状态——哪怕刚返回 true,下一毫秒别的线程就可能 unlock 并再次 lock,临界区逻辑仍需自身正确同步。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











