当前位置: 首页 > web >正文

【中间件】brpc_基础_单例

文章目录

  • brpc 单例
    • 1 实现核心机制
    • 2 代码结构解析
    • 3 关键设计点
    • 4 使用示例
    • 5 潜在改进与限制
    • 6 与标准单例实现的对比
    • 7 总结

brpc 单例

源码

1 实现核心机制

  • 基于 bthread_once 的线程安全初始化
    通过 BRPC 的 bthread_once 函数确保单例的初始化在多线程(bthread 环境)中仅执行一次。bthread_once 的作用类似于 pthread_once,但专为 BRPC 的用户态线程(bthread)设计,确保初始化函数在所有 bthread 中仅被调用一次。

  • 模板化设计
    使用模板类 SingletonOnBthreadOnce,允许用户将任意类封装为单例。用户只需通过 SingletonOnBthreadOnce<T>::get_instance() 即可获取单例实例,无需重复编写单例逻辑。

2 代码结构解析

// 模板类定义
template <typename T>
class SingletonOnBthreadOnce {
public:// 获取单例实例的入口方法static T* get_instance() {bthread_once(&once_control, init); // 确保 init 仅执行一次return instance;}private:// 初始化函数:创建单例对象static void init() {instance = new T();}// 静态成员:控制一次性初始化的标志static bthread_once_t once_control;// 静态成员:单例实例指针static T* instance;
};// 模板静态成员初始化(关键!)
template <typename T>
bthread_once_t SingletonOnBthreadOnce<T>::once_control = BTHREAD_ONCE_INIT;template <typename T>
T* SingletonOnBthreadOnce<T>::instance = nullptr;

3 关键设计点

  • 线程安全性
    通过 bthread_once 保证 init() 函数在所有 bthread 中仅执行一次,避免多线程竞争导致的多次实例化。

  • 延迟初始化(Lazy Initialization)
    单例实例在首次调用 get_instance() 时创建,避免程序启动时的全局初始化开销。

  • 内存管理
    单例对象通过 new 创建,但未提供销毁接口,依赖进程退出时操作系统自动回收内存。这种设计简化了实现,但可能导致资源泄漏(如文件句柄未释放)。

  • 模板静态成员定义
    静态成员 once_controlinstance 在模板类外部分别初始化为 BTHREAD_ONCE_INITnullptr,确保链接时正确生成符号。

4 使用示例

// 用户自定义类(需可访问构造函数)
class MyConfig {
public:MyConfig() { /* 初始化逻辑 */ }void load(const std::string& path) { /* ... */ }
};// 获取单例实例
MyConfig* config = SingletonOnBthreadOnce<MyConfig>::get_instance();
config->load("path/to/config");

5 潜在改进与限制

  • 构造函数访问权限
    要求用户类的构造函数为公有或对 SingletonOnBthreadOnce 开放友元。若需严格封装,用户需手动添加友元声明:

    class MyConfig {
    private:MyConfig() = default;friend class SingletonOnBthreadOnce<MyConfig>;
    };
    
  • 销毁机制缺失
    未提供 delete_instance() 方法,若需主动释放资源,可扩展模板类:

    static void destroy() {delete instance;instance = nullptr;once_control = BTHREAD_ONCE_INIT; // 重置以便重新初始化(需谨慎)
    }
    
  • 异常处理
    T 的构造函数抛出异常,bthread_once 会标记初始化未完成,下次调用 get_instance() 时将重试初始化。需确保构造函数幂等性或处理异常场景。

6 与标准单例实现的对比

特性BRPC 单例Meyer’s Singleton(C++11)
线程安全依赖 bthread_once,适用于 bthread 环境依赖静态局部变量初始化,原生线程安全
初始化时机延迟初始化延迟初始化
内存管理显式 new,依赖进程退出回收静态对象,自动析构(可能受析构顺序影响)
适用场景BRPC/bthread 项目通用 C++ 项目
代码复杂度需模板和静态成员定义极简(static T& instance() { static T obj; return obj; }

7 总结

singleton_on_bthread_once.h 提供了一种基于 BRPC 用户态线程(bthread)的单例模式实现,核心优势在于:

  • 线程安全初始化:通过 bthread_once 确保跨 bthread 的唯一性。
  • 低侵入性:用户类无需修改即可封装为单例。
  • 延迟加载:减少启动开销。

其局限性主要在于:

  • 依赖 BRPC 环境:不适用于非 BRPC 项目。
  • 内存泄漏风险:无显式销毁接口。
  • 构造函数权限要求:需用户类构造函数可访问。

适合在 BRPC 高并发服务中管理全局配置、资源池等需线程安全访问的单例对象。

http://www.xdnf.cn/news/4008.html

相关文章:

  • FreeRTOS学习系列·二值信号量
  • Linux查询日志常用命令
  • 解锁现代健康密码:科学养生新主张
  • 基于PLC的换热器温度控制系统设计
  • 状态模式(State Pattern)
  • 电子商务商家后台运营专员模板
  • C++ 中二级指针的正确释放方法
  • 【KWDB 创作者计划】_Ubuntu 22.04系统KWDB数据库安装部署使用教程
  • Qt中的UIC
  • Amazon Bedrock Converse API:开启对话式AI新体验
  • Qt开发:容器组控件的介绍和使用
  • 20、数据可视化:魔镜报表——React 19 图表集成
  • 408考研逐题详解:2009年第8题
  • Java后端程序员学习前端之CSS
  • Python matplotlib 成功使用SimHei 中文字体
  • 详解RabbitMQ工作模式之发布订阅模式
  • 基于C++实现的深度学习(cnn/svm)分类器Demo
  • Baklib知识中台:智能服务架构新实践
  • 【算法学习】递归、搜索与回溯算法(一)
  • python函数复习(形参实参,收集参数,关键字参数)
  • uniapp中用canvas绘制简单柱形图,小容量,不用插件——简单使用canvas
  • QT 在圆的边界画出圆
  • IP属地是我的定位吗?——解析两者区别
  • Python异步编程入门:从同步到异步的思维转变
  • VBA信息获取与处理专题五:VBA利用CDO发送电子邮件
  • 【外围电路】按键电路设计外接信号输入设计
  • Go小技巧易错点100例(二十九)
  • rollout 是什么:机器学习(强化学习)领域
  • 【Vue】Vue3源码解析与实现原理
  • 关于 dex2oat 以及 vdex、cdex、dex 格式转换