You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

何时在std::shared_lock中使用defer_lock参数?

std::shared_lock带defer_lock的构造函数:作用与适用场景

带std::defer_lock_t参数的std::shared_lock构造函数,核心作用是仅将锁对象与互斥量关联,但不立即获取锁,把锁的获取时机交给开发者手动控制,以此满足更灵活的同步需求。

核心作用

  • 拆分"关联互斥量"与"获取锁"两个动作:让你可以先把锁和目标互斥量绑定,之后根据业务逻辑决定什么时候加锁。
  • 适配复杂锁操作:配合lock()、try_lock()、lock_for()等成员函数,实现阻塞加锁、尝试加锁、超时加锁等多样化的同步逻辑。

适用场景

1. 配合条件变量使用

当用shared_lock搭配条件变量时,通常需要在等待前解锁,被唤醒后重新加锁。用defer_lock构造锁对象,能先关联互斥量,再手动加锁,之后由条件变量自动处理解锁/重锁流程:

std::shared_mutex mtx;
std::condition_variable_any cv;
bool data_ready = false;

void process_data() {
    std::shared_lock<std::shared_mutex> lock(mtx, std::defer_lock);
    lock.lock(); // 手动获取共享锁
    // wait会自动解锁,直到条件满足后重新加锁
    cv.wait(lock, []{ return data_ready; });
    // 处理已准备好的数据
}

2. 多锁顺序控制(避免死锁)

当需要同时获取多个共享锁时,直接在构造时加锁可能因为加锁顺序不一致导致死锁。用defer_lock先关联所有锁,再通过std::lock()一次性加锁,能保证安全的加锁顺序:

std::shared_mutex mtx_a, mtx_b;

void cross_resource_operation() {
    std::shared_lock<std::shared_mutex> lock_a(mtx_a, std::defer_lock);
    std::shared_lock<std::shared_mutex> lock_b(mtx_b, std::defer_lock);
    
    std::lock(lock_a, lock_b); // 原子性地同时获取两个锁,避免死锁
    // 操作mtx_a和mtx_b保护的资源
}

3. 尝试非阻塞获取锁

如果希望尝试获取锁但不阻塞等待,用defer_lock构造后调用try_lock(),可以在获取失败时立即执行备用逻辑,而不会卡在构造阶段:

std::shared_mutex mtx;

void try_process() {
    std::shared_lock<std::shared_mutex> lock(mtx, std::defer_lock);
    if (lock.try_lock()) {
        // 成功获取共享锁,处理资源
    } else {
        // 获取失败,执行降级逻辑(比如返回提示、跳过操作)
    }
}

简单来说,这个构造函数的存在,就是为了让开发者摆脱"构造即加锁"的固定流程,针对不同的同步场景,灵活控制锁的生命周期和获取时机。

内容的提问来源于stack exchange,提问作者gongliming7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 17:06:20