C++是否提供线程安全的引用计数器?标准库或VS扩展有无对应实现?
问题
标准C++库中是否存在线程安全的引用计数器类,或是Visual Studio中提供了对应的扩展?还是我需要完全从零编写这类对象?
我希望得到一个类似shared_ptr那样纯用于执行引用计数的对象,区别在于它可以跨多线程准确计数,且不需要管理任何对象的生命周期。shared_ptr及其相关结构的优势在于它们已经定义好了所有需要的拷贝构造函数和赋值运算符,在我看来这些是C中最容易出错的部分:C构造函数之于C++,就好比开球之于美式橄榄球。
struct Fun { // 这个成员的行为我很满意,除了两个问题: // - 不必要的内存分配(次要) // - 如果跨线程共享,引用计数的结果只是估计值(严重) std::shared_ptr<int> smartPtr {new int}; // 这是我想找的理想对象 // + 只分配引用计数需要的控制块 // + 当多个线程都持有引用时,refCount.unique()的返回值符合实际情况 // 我可以100%确定当前是不是最后一个引用 std::object_of_desire refCount; // 不需要显式写拷贝构造函数或者赋值运算符 // + 这个类的两个成员都已经帮你处理好了这些繁琐的逻辑 // 所以我可以随意传递Fun对象,它的行为完全符合预期,只会做浅拷贝/移动以及引用计数 Fun(); ~Fun(){ if(refCount.unique()){ smart_assert("我发誓refCount真的是唯一引用,出错我担责"); } } };
回答
标准C++没有单独的原生纯引用计数类,但你完全不需要从零实现,直接用现有std::shared_ptr的特性就能改造出完全符合你要求的对象,也不需要依赖Visual Studio的专属扩展。
std::shared_ptr的引用计数本身就是线程安全的:计数的增减都是原子操作,只要你没有在其他线程同时修改同一个引用组的计数,unique()的返回结果是100%准确的。你只需要给shared_ptr绑定一个无意义的占位对象,就能实现你要的纯计数效果,不需要管理任何实际业务对象的生命周期。
推荐你用std::make_shared分配占位对象,它会把控制块和占位对象合并在同一块内存分配,开销极低:
#include <memory> struct Fun { // 完全符合你要求的引用计数对象 std::shared_ptr<void> refCount = std::make_shared<char>(); Fun() = default; ~Fun(){ if(refCount.unique()){ // 这里的判断完全准确,没有多线程同步问题 smart_assert("我发誓refCount真的是唯一引用,出错我担责"); } } };
这个实现完全满足你的所有要求:
- 不需要手动实现任何拷贝、赋值、移动相关的函数,
shared_ptr原生帮你处理好了所有逻辑,你可以随意传递Fun对象,行为完全符合预期 - 线程安全符合C++标准要求,所有主流编译器(包括Visual Studio)的实现都支持
- 开销极小,只有一次内存分配,占位的char只有1字节,额外开销可以忽略
内容的提问来源于stack exchange,提问作者Anne Quinn
相关产品推荐
相关产品推荐

