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

如何面向未来兼容C++ std::shared_ptr、std::unique_ptr的线程安全并发访问

C++智能指针并发访问跨版本兼容实现方案

核心设计思路

  • 基于标准内置的__cplusplus宏自动检测C++版本,切换底层实现逻辑,无需手动修改编译配置
  • 宏封装层与业务代码完全解耦,后续C++20原子智能指针特性普及后,仅需修改宏定义即可完成升级,业务逻辑无需调整
  • 严格遵循前提结论设计,不引入额外不必要的同步开销,兼顾性能与安全性

跨版本适配宏定义

#include <atomic>
#include <memory>
#include <mutex>

// 自动识别C++版本,切换实现
#if __cplusplus >= 202002L
/************************************* C++20及以上版本实现 *************************************/
// 基础原子操作封装,当前兼容C++17风格调用,后续可直接切换为原生atomic<shared_ptr>实现
#define SHARED_GET(public_shared) std::atomic_load(&public_shared)
#define SHARED_SET(public_shared, new_val) std::atomic_store(&public_shared, new_val)
#define UNIQUE_GET(public_unique) std::atomic_load(&public_unique)
#define UNIQUE_SET(public_unique, new_val) std::atomic_store(&public_unique, new_val)

/* 待编译器对std::atomic<std::shared_ptr>支持普及后,可替换为以下原生无锁实现,业务代码无需修改
#define SHARED_GET(atomic_public_shared) atomic_public_shared.load()
#define SHARED_SET(atomic_public_shared, new_val) atomic_public_shared.store(new_val)
#define UNIQUE_GET(atomic_public_unique) atomic_public_unique.load()
#define UNIQUE_SET(atomic_public_unique, new_val) atomic_public_unique.store(new_val)
*/

#else
/************************************* C++17及更早版本实现 *************************************/
#define SHARED_GET(public_shared) std::atomic_load(&public_shared)
#define SHARED_SET(public_shared, new_val) std::atomic_store(&public_shared, new_val)
#define UNIQUE_GET(public_unique) std::atomic_load(&public_unique)
#define UNIQUE_SET(public_unique, new_val) std::atomic_store(&public_unique, new_val)
#endif

/************************************* 通用业务层宏定义 *************************************/
// 从公共共享的shared_ptr实例创建本地无竞争副本
#define MAKE_LOCAL_SHARED(local_name, public_shared) auto local_name = SHARED_GET(public_shared)

// shared_ptr指向对象访问保护,需传入绑定到对应对象的互斥量
#define BEGIN_USE_SHARED_TGT(local_shared, mutex_obj) \
do { \
    std::lock_guard<std::mutex> guard(mutex_obj);

#define END_USE_SHARED_TGT } while(0)

// unique_ptr指向对象访问保护,队列保证独占场景下无锁,仅做语义标记
#define BEGIN_USE_UNIQUE_TGT(local_unique)
#define END_USE_UNIQUE_TGT

使用示例

// 公共资源定义
std::shared_ptr<MyBusinessClass> g_shared_biz_obj;
std::unique_ptr<MyBusinessClass> g_unique_biz_obj;
std::mutex g_shared_biz_mutex; // 与g_shared_biz_obj指向的对象绑定

// 业务线程逻辑
void worker_thread() {
    // 1. 生成shared_ptr本地副本,无并发竞争
    MAKE_LOCAL_SHARED(local_shared, g_shared_biz_obj);
    
    // 2. 安全访问shared_ptr指向的对象
    BEGIN_USE_SHARED_TGT(local_shared, g_shared_biz_mutex)
        local_shared->process_data();
        local_shared->update_status();
    END_USE_SHARED_TGT;

    // 3. 接收队列传递的unique_ptr独占实例
    auto local_unique = std::move(g_unique_biz_obj);
    // 无需加锁直接访问,仅做语义标记
    BEGIN_USE_UNIQUE_TGT(local_unique)
        local_unique->single_thread_process();
    END_USE_UNIQUE_TGT;
}

注意事项

  • 所有公共全局/跨线程传递的智能指针实例,必须仅通过上述SHARED_GET/SHARED_SET/UNIQUE_GET/UNIQUE_SET宏访问,禁止直接读写操作
  • unique_ptr的无锁访问依赖队列的独占保证,必须确保同一时间只有一个线程持有该unique_ptr实例
  • 保护指向对象的互斥量需要与对应智能指针指向的对象绑定管理,避免出现用错互斥量导致的并发问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 03:45:08