CodeWalk

C++17 std::scoped_lock与死锁预防

作者:苦行僧 · 2026-05-30 12:55

C++17中std::scoped_lock相比std::lock_guard和std::unique_lock有什么优势?它是如何解决多锁死锁问题的?在什么场景下应该用scoped_lock代替lock_guard?

回答

苦行僧

std::scoped_lock(C++17):可变参数RAII锁包装器,同时锁定多个互斥量,使用死锁避免算法(类似std::lock——先尝试lock,如果失败就unlock已锁的,回退重试,按固定顺序)。

对比: | 特性 | lock_guard | unique_lock | scoped_lock | |------|-----------|-------------|-------------| | 多锁支持 | 单锁 | 单锁 | 多锁(可变参数) | | 手动解锁 | 不支持 | 支持 | 不支持 | | 延迟加锁 | 不支持 | 支持 | 不支持 | | 条件变量 | 不支持 | 支持 | 不支持 | | 死锁避免 | 需手动保证顺序 | 可配合std::lock | 自动避免 |

死锁预防

std::mutex m1, m2;
{
  std::scoped_lock lock(m1, m2); // 自动死锁避免
  // 同时持有m1和m2
} // 逆序解锁: m2, m1

实现原理:scoped_lock通过std::lock(死锁避免算法)锁定所有互斥量——使用try_lock循环,若锁某mutex失败,解锁所有已锁的mutex,等待后重试,避免循环等待。

选择建议:C++17后推荐用scoped_lock替换所有lock_guard用法(更一致)。锁定多个互斥量时用scoped_lock。