线程安全的map

实现多线程下的insert find erase begin end 等操作,输入的key或者value为指针的时候可以根据输入的releasefu回调实现内存释放

/*******************************************************
 文件名:CSafeMap.h
 作者:ll
 描述:线程安全的map
 版本:v1.0
 日期:2023-03-10
 注意事项: key值或者value 使用了指针一定要传入释放函数来对数据空间进行释放
 *******************************************************/
#ifndef CSAFEDATAMAP_H
#define CSAFEDATAMAP_H
#include <map>
#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
template<typename T,typename W,typename Container = std::map<T,W>>

class MSafeMap
{
public:
    using map_type=Container;
    using key_type=typename map_type::key_type;
    using size_type=typename map_type::size_type;
    using safe_iter = typename map_type::iterator;
    using safe_const_iter = typename map_type::const_iterator;
    MSafeMap()=default;
    ~MSafeMap(){Clear();std::cout<<"release"<<std::endl;}

    MSafeMap(const MSafeMap&)=delete;
    MSafeMap(MSafeMap&&)=default;
    MSafeMap& operator=(const MSafeMap&)=delete;
    MSafeMap& operator=(MSafeMap&&)=delete;

    W & operator[](const T &l_key)
    {
        std::lock_guard<std::mutex>lock (m_Mutex);
        return m_dataMap[l_key];
    }


public:
    bool Insert(const std::pair<T,W> &l_data )
    {
        std::unique_lock<std::mutex>lock (m_Mutex);
        m_dataMap.insert(l_data);
        lock.unlock();
        m_Cv.notify_one();
        return true;
    }
    void Clear()
    {
        std::unique_lock<std::mutex>lock (m_Mutex);
        if(m_releaseFun)
        {
            for(auto it :m_dataMap)
            {
                m_releaseFun(const_cast<T&>(it.first),const_cast<W&>(it.second));
            }
            m_dataMap.clear();
            return;
        }
        m_dataMap.clear();
    }
    typedef void (*ReleaseFun)(T& p_releaseKey,W &p_releaseVal);
    const int Size() const
    {
        std::lock_guard<std::mutex>lock (m_Mutex);
        return m_dataMap.size();
    }
    const std::vector<T> Keys() const
    {
        std::lock_guard<std::mutex>lock (m_Mutex);
        std::vector<T> l_keys;
        for(auto iter:m_dataMap)
        {
            l_keys.emplace_back(iter.first);
        }
        return l_keys;
    }
    const std::vector<W> Values() const
    {
        std::lock_guard<std::mutex>lock (m_Mutex);
        std::vector<W> l_values;
        for(auto iter:m_dataMap)
        {
            l_values.emplace_back(iter.second);
        }
        return l_values;
    }
    bool  value(const T &l_key,W &l_value,const int32_t& p_nTimeOut=100)
    {
        std::unique_lock<std::mutex> lock(m_Mutex);
        bool l_bOk = m_Cv.wait_for(lock, std::chrono::milliseconds(p_nTimeOut), [&]() {return m_dataMap.count(l_key)>0;});
        if(!l_bOk)
        {
            lock.unlock();
            m_Cv.notify_all();
            return false;
        }
        else
        {
            l_value = m_dataMap[l_key];
            lock.unlock();
            m_Cv.notify_all();
            return true;
        }
    }
    safe_iter Begin()
    {
        std::unique_lock<std::mutex> lock(m_Mutex);
        m_Cv.wait(lock, [&]() {return m_dataMap.size()>0;});
        return m_dataMap.begin();
    }
    safe_iter End()
    {
        std::unique_lock<std::mutex> lock(m_Mutex);
        m_Cv.wait(lock, [&]() {return m_dataMap.size()>0;});
        return m_dataMap.end();
    }
    safe_const_iter ConstBegin()const
    {
        std::unique_lock<std::mutex> lock(m_Mutex);
        m_Cv.wait(lock, [&]() {return m_dataMap.size()>0;});
        return m_dataMap.cbegin();
    }
    safe_const_iter ConstEnd()const
    {
        std::unique_lock<std::mutex> lock(m_Mutex);
        m_Cv.wait(lock, [&]() {return m_dataMap.size()>0;});
        return m_dataMap.cend();
    }
    safe_iter  Erase(safe_const_iter iter){
        std::unique_lock<std::mutex> lock(m_Mutex);
        if(m_releaseFun)
        {
            m_releaseFun(const_cast<T&>(iter->first),const_cast<T&>(iter->second));
        }
        return m_dataMap.erase(iter);
    }
    safe_iter Erase(safe_iter iter){
        std::unique_lock<std::mutex> lock(m_Mutex);
        if(m_releaseFun)
        {
            m_releaseFun(const_cast<T&>(iter->first),const_cast<T&>(iter->second));
        }
        return m_dataMap.erase(iter);
    }
    size_type Erase(const key_type& key){
        std::unique_lock<std::mutex> lock(m_Mutex);
        if(m_releaseFun)
        {
            m_releaseFun(const_cast<T&>(m_dataMap.find(key)->first),const_cast<W&>(m_dataMap.find(key)->second));
        }
        return m_dataMap.erase(key);
    }
    safe_iter Find(const key_type &key)
    {
        std::unique_lock<std::mutex> lock(m_Mutex);
        return m_dataMap.find(key);
    }
    safe_const_iter Find(const key_type &key) const
    {
        std::unique_lock<std::mutex> lock(m_Mutex);
        return m_dataMap.find(key);
    }
    void SetReleaseFun(ReleaseFun fun)
    {
        std::unique_lock<std::mutex> lock(m_Mutex);
        m_releaseFun = fun;
    }


private:
    Container m_dataMap;                                //map
    mutable std::mutex		m_Mutex;			        //队列锁
    mutable std::condition_variable m_Cv;				//条件变量
    ReleaseFun m_releaseFun = nullptr;                            //释放内存函数
};
#endif //CSAFEDATAMAP_H

 

posted @ 2023-03-10 14:49  浅情1314  阅读(55)  评论(0编辑  收藏  举报