首页IT科技c++多线程有几种实现方法(c++ 程序通用多线程单例设计 c++ web 框架设计经验谈)

c++多线程有几种实现方法(c++ 程序通用多线程单例设计 c++ web 框架设计经验谈)

时间2025-05-05 08:17:06分类IT科技浏览3319
导读:设计 c++ web 框架时候,想要一个框架缓存类,很多通用缓存类是用字符保存,作为框架内置就不要序列和反序列了,因为框架内部使用。...

设计 c++ web 框架时候           ,想要一个框架缓存类                ,很多通用缓存类是用字符保存     ,作为框架内置就不要序列和反序列了           ,因为框架内部使用           。

想给自己的paozhu c++ web 框架添加缓存类                 ,参考了springboot 于是确定用单例设计模式缓存类模板                。

c++11后静态变量已经统一为线程安全了     ,网络各种茴香豆几种吃法现在变成一种安全吃法     。

因为框架时候了多线程     ,也要求最低c++20                 ,所以直接使用新标准单例模式      。

因为需要保存多种类型           ,于是设计为模版接口     ,这样一个通用设计 缓存模型想好了                ,然后就是设计类库API           ,需要兼容数组和单一对象                。

也要有超时,于是我们确定了基础结构

因为我想以后还要动态库也能使用                ,于是用了一个静态函数做单例

template <typename BASETYPE_T> std::map<std::size_t, BASETYPE_T> &get_pz_cache() { static std::map<std::size_t, BASETYPE_T> instance; return instance; }

模版类需要兼顾数组和单个对象于是统一保存为vector数组                ,然后套入map对象,因为我们要用size_t做hash键值           ,这样方便统一长度           。

然后根据不同api返回不同类型      。

先看详细代码                ,后面讲一个map插入失败情况

template <typename BASE_TYPE> class pzcache { private: pzcache(){}; ~pzcache(){}; pzcache(const pzcache &); pzcache &operator=(const pzcache &); public: struct data_cache_t { std::vector<BASE_TYPE> data; unsigned int exptime = 0; }; public: void save(std::size_t hashid, BASE_TYPE &data_list, int expnum = 0, bool cover_data = false) { std::map<std::size_t, data_cache_t> &obj = get_pz_cache<data_cache_t>(); struct data_cache_t temp; temp.data.push_back(data_list); if (expnum != 0) { temp.exptime = http::timeid() + expnum; } else { temp.exptime = 0; } std::unique_lock<std::mutex> lock(editlock); auto [_, success] = obj.insert({hashid, temp}); if (!success) { if (cover_data) { obj[hashid] = temp; } else { obj[hashid].exptime = temp.exptime; } } } void save(std::size_t hashid, std::vector<BASE_TYPE> &data_list, int expnum = 0, bool cover_data = false) { std::map<std::size_t, data_cache_t> &obj = get_pz_cache<data_cache_t>(); struct data_cache_t temp; temp.data = data_list; if (expnum != 0) { temp.exptime = http::timeid() + expnum; } else { temp.exptime = 0; } std::unique_lock<std::mutex> lock(editlock); auto [_, success] = obj.insert({hashid, temp}); if (!success) { if (cover_data) { obj[hashid] = temp; } else { obj[hashid].exptime = temp.exptime; } } } bool remove(std::size_t hashid) { std::map<std::size_t, data_cache_t> &obj = get_pz_cache<data_cache_t>(); std::unique_lock<std::mutex> lock(editlock); auto iter = obj.find(hashid); if (iter != obj.end()) { obj.erase(iter++); return true; } return false; } void remove_exptime() { std::map<std::size_t, data_cache_t> &obj = get_pz_cache<data_cache_t>(); unsigned int nowtime = http::timeid(); std::unique_lock<std::mutex> lock(editlock); for (auto iter = obj.begin(); iter != obj.end();) { if (iter->second.exptime == 0) { continue; } if (iter->second.exptime < nowtime) { obj.erase(iter++); } } } void clear() { std::map<std::size_t, data_cache_t> &obj = get_pz_cache<data_cache_t>(); std::unique_lock<std::mutex> lock(editlock); obj.clear(); } int check(std::size_t hashid) { std::map<std::size_t, data_cache_t> &obj = get_pz_cache<data_cache_t>(); unsigned int nowtime = http::timeid(); std::unique_lock<std::mutex> lock(editlock); auto iter = obj.find(hashid); if (iter != obj.end()) { if (iter->second.exptime == 0) { return 0; } int temp = (int)(iter->second.exptime - nowtime); if (temp == -1) { return -2; } return temp; } return -1; } int update(std::size_t hashid, int exptime = 0) { std::map<std::size_t, data_cache_t> &obj = get_pz_cache<data_cache_t>(); unsigned int nowtime = http::timeid() + exptime; if (exptime == 0) { nowtime = 0; } std::unique_lock<std::mutex> lock(editlock); auto iter = obj.find(hashid); if (iter != obj.end()) { if (iter->second.exptime == 0) { iter->second.exptime = nowtime; return 0; } iter->second.exptime = nowtime; return 1; } return -1; } std::vector<BASE_TYPE> get_array(std::size_t hashid) { std::map<std::size_t, data_cache_t> &obj = get_pz_cache<data_cache_t>(); unsigned int nowtime = http::timeid(); std::unique_lock<std::mutex> lock(editlock); auto iter = obj.find(hashid); if (iter != obj.end()) { if (iter->second.exptime == 0) { return iter->second.data; } if (iter->second.exptime >= nowtime) { return iter->second.data; } else { obj.erase(iter++); } } lock.unlock(); std::vector<BASE_TYPE> temp; return temp; } BASE_TYPE get(std::size_t hashid) { std::map<std::size_t, data_cache_t> &obj = get_pz_cache<data_cache_t>(); unsigned int nowtime = http::timeid(); std::unique_lock<std::mutex> lock(editlock); auto iter = obj.find(hashid); if (iter != obj.end()) { if (iter->second.exptime == 0) { if (iter->second.data.size() > 0) { return iter->second.data[0]; } } if (iter->second.exptime >= nowtime) { if (iter->second.data.size() > 0) { return iter->second.data[0]; } } else { obj.erase(iter++); } } lock.unlock(); BASE_TYPE temp; return temp; } static pzcache &conn() { static pzcache instance; return instance; } public: std::mutex editlock; };

auto [_, success] = obj.insert({hashid, temp});

这个map insert 方法如果存在会插入失败     ,于是我用API指定是更新过期时间或删除重新添加           ,这一步巧妙利用了map这个特性                 ,需要c++17以上                。

然后使用方式就是很简单了

pzcache<std::string> &temp_cache = pzcache<std::string>::conn();

我们缓存一个string 对象     ,首先取得单例           。

pzcache<std::string> &temp_cache = pzcache<std::string>::conn();       std::string namestring = "testname"; std::size_t cache_hashid = std::hash<std::string>{}(namestring); if (temp_cache.check(cache_hashid) > -1) { client << " 已经存在     ,不需要再存 "; } else { std::string cache_data = "This cache content!"; temp_cache.save(cache_hashid, cache_data, 30); client << "缓存新的内容"; }

然后我们在其它线程使用

pzcache<std::string> &temp_cache = pzcache<std::string>::conn(); std::string namestring = "testname"; std::size_t cache_hashid = std::hash<std::string>{}(namestring); std::string cache_data = temp_cache.get(cache_hashid);

是不是很简单                 ,c++ 强大的模板能力           ,一个通用类库设计好了     ,而且简单好用

欢迎使用 国产 C++ web 框架 paozhu 1.2.0 发布

源代码里面更多的设计模式可以参考                ,框架LICENSE反正为MIT模式           ,大家商用也没有问题。

https://github.com/hggq/paozhu

声明:本站所有文章,如无特殊说明或标注                ,均为本站原创发布                。任何个人或组织                ,在未征得本站同意时,禁止复制           、盗用                、采集     、发布本站内容到任何网站      、书籍等各类媒体平台                。如若本站内容侵犯了原著者的合法权益           ,可联系我们进行处理。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
网创是啥(什么样的网创最靠谱-到底有没有靠谱的网创项目)