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

【中间件】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 高并发服务中管理全局配置、资源池等需线程安全访问的单例对象。

相关文章:

  • Scrapy分布式爬虫实战:高效抓取的进阶之旅
  • 直方图反向投影
  • 多语言笔记系列:Polyglot Notebooks 中运行 BenchmarkDotnet 基准测试
  • Hive安装与配置教程
  • 《冰雪三职业》:战士玩法攻略!
  • UniGetUI 使用指南:轻松管理 Windows 软件(包括CUDA)
  • 模型训练实用之梯度检查点
  • 头歌实验MySQL数据库 - 复杂查询(二)
  • 深入解析Semantic Kernel中的聊天历史记录对象
  • Gradio全解20——Streaming:流式传输的多媒体应用(6)——RT-DETR模型构建视频流目标检测系统
  • STM32教程:DMA原理及结构分析(基于STM32F103C8T6最小系统板标准库开发)*详细教程*
  • C++类与对象深度解析:从基础到应用
  • 《Java 高并发程序设计》笔记
  • 【言语理解】片段阅读之标题拟定(5)
  • Deepseek基础-api key申请及应用(java)、硅基流动api key申请及应用(dify)
  • 《Effective java》 第三版 核心笔记
  • 怎么才能找到自己的天赋?
  • 图片批量处理JPGC 深度测评:智能压缩 + 多线程加速
  • RFID(无线射频识别)技术在牧场中的结合智能助手应用
  • 编译原理期末重点-个人总结——1 概论
  • 多省份晒出“五一”旅游“成绩单”:北京游客接待量、旅游消费创历史新高
  • 赵心童世锦赛历史性夺冠,你今天打斯诺克很可能订不到位
  • 立夏的野火饭
  • 贵州游船侧翻248名消防员已在搜救
  • 中海油高管调整:刘永杰、刘小刚任副总裁
  • 9米长林肯车开进安徽“皖南川藏线”致拥堵数小时,车主回应争议称配合调查