C++ 容器 线程安全包装

容器 线程安全包装

实现对容器使用线程锁的包装模板类,省去重复 写各种简单的容器线程包装

一些前置工具来自于 https://gitee.com/keybox/actor-library/blob/master/actor/commons/commons_utils.h

互斥锁包装模板

template <typename T,typename Lock = std::mutex>
class LContainer{
    //    struct Lock{     //要求 Lock 类必须实现的方法
    //        void lock(){}
    //        bool try_lock(){}
    //        void unlock(){}
    //    };
public:
    LContainer():__lock(new Lock()){}
    LContainer(const T& data):__lock(new Lock()),__data(data){}
    LContainer(T&& data):__lock(new Lock()),__data(std::move(data)){}

public: //重置内部数据
    auto operator=(const T& data){
        reset(data);
        return lock();
    }
    auto operator=(T&& data){
        reset(data);
        return lock();
    }

    auto operator->(){return lock();}            //写
    auto operator->() const {return lock();} //读
    auto operator*() {return lock();}             //写
    auto operator*() const {return lock();}   //读
//    operator const bool() const {auto l = lock();return this->__data;}

public:
    //尝试上锁
    auto try_lock(){return defer_unlock(__lock->try_lock());} 
    auto try_lock() const {return defer_unlock(__lock->try_lock());}
  
    //上锁
    auto lock(){
        __lock->lock();
        return defer_unlock();
    }

    auto lock() const {
        __lock->lock();
        return defer_unlock();
    }

public:
    //尝试交换内部数据
    bool try_swit(T& data){
        if (!__lock->try_lock())return false;
        auto l = defer_unlock();
        std::swap(std::ref(data),__data);
        return true;
    }
   //尝试重置内部数据为其他
    bool try_reset(const T& data){
        if (!__lock->try_lock())return false;
        auto l = defer_unlock();
        __data = data;
        return true;
    }
   
    bool try_reset(T&& data){
        if (!__lock->try_lock())return false;
        auto l = defer_unlock();
        __data = data;
        return true;
    }

    void reset(const T& data){
        auto l = lock();
        __data = data;
    }

    void reset(T& data){
        auto l = lock();
        std::swap(data,__data);
    }

protected:
    //解锁器 //写锁 (上锁有效性)  //当上锁无效时将返回false的锁代理
    auto defer_unlock(bool vaild = true)
    {return make_defer_ref([this](){__lock->unlock();},__data,vaild);}
   //常量方法 解锁器 //读锁  //当内容数据不是指针时
    template<typename T1 = T,Type_Is::is_no_pointer<T1>* = nullptr>
    auto defer_unlock(bool vaild = true) const
    {return make_defer_ref([this](){__lock->unlock();},__data,vaild);}
   //内部数据是指针
    template<typename T1 = T,Type_Is::is_pointer<T1>* = nullptr>
    auto defer_unlock(bool vaild = true) const{
        const auto& data = *this->__data;
        auto* rul_ptr = &data;
        return make_defer_ua([this](){__lock->unlock();},rul_ptr,vaild);
    }

protected:
    T __data;                         //要保护的数据 //可以是容器或变量
    PtrAgent<Lock> __lock;  //线程锁

   // friend struct iterator<LContainer>;  //还没实现完
};


读写锁包装模板

//通过继承LContainer 互斥锁模板,重新实现 const 函数完成
template <typename T,typename Lock = std::shared_mutex>
class RWContainer : public LContainer<T,Lock>{
//    struct Lock{  //锁类必须存在这些方法
//        void lock(){}
//        void lock_shared(){}
//        bool try_lock(){}
//        bool try_lock_shared(){}
//        void unlock(){}
//        void unlock_shared(){}
//    };
public:
    using LContainer<T,Lock>::LContainer;
    //修改是上写锁的,但返回的值是上读锁的
    auto operator=(const T& data){
        this->reset(data);
        return lock_shared();
    }
    auto operator=(T&& data){
        this->reset(data);
        return lock_shared();
    }

    auto operator->() const {return lock_shared();}
    auto operator*() const {return lock_shared();}
    auto operator->() {return LContainer<T,Lock>::operator->();}
    auto operator*() {return LContainer<T,Lock>::operator*();}
//    operator const bool() const {auto l = lock_shared();return this->__data;}

public:
    //尝试上读锁
    auto try_lock_shared() const {
        return defer_unlock_shared(this->__lock->try_lock_shared());
    }
   //上读锁
    auto lock_shared() const {
        this->__lock->lock_shared();
        return defer_unlock_shared();
    }

protected:
    //读锁器 //内容数据是指针
    template<typename T1 = T,Type_Is::is_pointer<T1>* = nullptr>
    auto defer_unlock_shared(bool vaild = true) const{
        const auto& data = *this->__data;
        auto* rul_ptr = &data;
        return make_defer([this](){this->__lock->unlock_shared();},rul_ptr,vaild);
    }
   //读锁器 //内容数据不是指针
    template<typename T1 = T,Type_Is::is_no_pointer<T1>* = nullptr>
    auto defer_unlock_shared(bool vaild = true) const
    {return make_defer_ref([this](){this->__lock->unlock_shared();},this->__data,vaild);}

protected:
   // friend struct iterator<RWContainer>; //还没有完成
};


读写锁测试

ReThreadPool是一个很简单的线程池,来自 https://gitee.com/keybox/actor-library/blob/master/actor/thread_pool.h

void rwcontent_test(uint64_t count = 1000,uint64_t tcount = 15,uint64_t rcount = 1){

    auto con = RWContainer<uint64_t>();

    uint64_t a = 0;
    for (uint64_t i = 0;i < count; i++){
        a += 1 * tcount;
    }

    auto pool = ReThreadPool(tcount,[&](){
        for (uint64_t i = 0;i < count; i++){
            (*con).data() += 1;
        }
    });

    auto p_pool = ReThreadPool(rcount,[&](){
        for (uint64_t i = 0;i<10;i++){
            const auto& c = con;
            std::cout<<(*c).data()<<std::endl;
        }
    });

    pool.join();
    p_pool.join();

    std::cout<<a<<"  "<<(*con).data()<<std::endl;

}

源码地址

https://gitee.com/keybox/actor-library/blob/master/actor/commons/concurrent_commons.h

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值