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

跨不同回调函数管理std::unique_lock加解锁的实现方案咨询

实现方案

直接通过std::unique_lock的移动语义将锁的所有权转移到类成员变量即可,符合C++标准设计语义,同时保证异常安全,完整实现如下:

#include <mutex>
#include <condition_variable>

// 第三方提供的Foo类定义,无需修改
class Foo
{
public:
  void bar() {
    before_bar_callback();
    // 第三方内部逻辑
    after_bar_callback();
  }
private:
  virtual void before_bar_callback() {}
  virtual void after_bar_callback() {}
};

class MyFoo : public Foo {
private:
    bool flag = false;
    std::mutex mtx;
    std::condition_variable cond;
    // 用于持有跨两个回调的锁实例
    std::unique_lock<std::mutex> held_lock;

    void before_bar_callback() override {
        std::unique_lock<std::mutex> local_lock(mtx);
        // 等待条件触发,自带谓词可规避虚假唤醒问题
        cond.wait(local_lock, [&]{ return flag; });
        // 转移锁所有权到成员变量,本地锁离开作用域不会释放
        held_lock = std::move(local_lock);

        // ... 此处放置原有do some stuff逻辑
    }

    void after_bar_callback() override {
        // ... 此处放置原有do some more stuff逻辑
        flag = false;
        // 主动释放锁,也可省略等待held_lock析构时自动释放
        held_lock.unlock();
    }

public:
    // 对外提供触发接口,由其他线程调用唤醒等待逻辑
    void notify() {
        std::lock_guard<std::mutex> lock(mtx);
        flag = true;
        cond.notify_one();
    }
};
说明
  • std::unique_lock本身支持所有权转移,存储为类成员变量完全符合设计语义,由于before_bar_callback和after_bar_callback由Foo::bar所在的同一个线程顺序调用,不存在并发操作held_lock的情况,线程安全。
  • 异常安全保障:即使Foo::bar在两个回调之间的内部逻辑抛出异常,MyFoo对象析构时会自动调用held_lock的析构函数释放互斥锁,不会出现死锁。
  • 无需修改第三方Foo类的任何实现,仅通过继承重写虚函数即可满足需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 06:09:04