当前位置: 首页 > news >正文

住房和城乡建设部办公厅网站合肥专业做网站的公司

住房和城乡建设部办公厅网站,合肥专业做网站的公司,旅游网站源码免费下载,搜索引擎排名原理一、数据容器 在前面分析过,不管是线程任务的封装还是同步数据队列的封装,都是需要一个数据结构的。一用来说,如果没有什么特殊的原因,开发者都是使用STL中数据结构。比如前面经常见到的std::queue,std::deque,std::vector,std::…

一、数据容器

在前面分析过,不管是线程任务的封装还是同步数据队列的封装,都是需要一个数据结构的。一用来说,如果没有什么特殊的原因,开发者都是使用STL中数据结构。比如前面经常见到的std::queue,std::deque,std::vector,std::unordered_map,std::list等等。
但是大家都知道,标准库中的容器一般都是非线程安全的,所以在线程池中如果想使用这些容器,就需要自己处理一下相关的线程安全相关的控制。

二、线程的安全性

所谓线程的安全数据访问,其实在前面学习了很多方法和技术。在不同的平台上,可能也有不小的差异。但标准库的出现还是让这种差异弥合了很多。一般来说,在保证线程数据安全访问,也就是同步控制上,使用锁。也就是lock来锁住mutex。
但如何安全的使用锁,这就有很多技巧了。包括锁的粒度的大小,锁使用的时机和应用的地方。在下面的例子中,大家可以分析一下,如何进行更好的优化。

三、接口封装

数据结构如果使用标准库的容器,就会有一个问题,标准库的不同的容器,其对外的接口的名称是不相同的。当然,如何不对这些容器进行泛化,只是单纯的使用某种容器,就没有这种问题。但是如何想使用模板来整体使用这些容器呢?
这就需要一些辅助的技术来控制,既要达到在上层的接口统一性,又要保证在调用下层的库接口时的安全。这时,就用到了模板的SFINAE技术,当然,在高版本中,也可以使用Concepts(概念)。

四、实例

通过上面的分析,基本明白了这个抽象的数据结构封装的方式,其实就是在STL库的上层再封装一层,同时要保证多线程访问时的安全性,看下面的例子:
1、首先对原TaskQueue进行改造:

#ifndef __TASKBUCKET_H__
#define __TASKBUCKET_H__#include "common.h"
#include <iostream>
#include <mutex>
#include <queue>template <typename T, typename Con = std::queue<T>> class TaskBucket final : public NoCopy {
public:TaskBucket() {}~TaskBucket() {}public:void Pop() { this->queue_.pop(); }void Push(T t) {std::cout << "Push bool:" << HasMemFuncCpp11<Con>::value << std::endl;std::unique_lock lock(this->mu_);if constexpr (HasMemFuncCpp11<Con>::value) {this->queue_.emplace_back(t);}}T Front() {std::unique_lock lock(this->mu_);return this->queue_.front();}T Back() {std::unique_lock lock(this->mu_);return this->queue_.back();}auto PopFront() {std::cout << "PopFront bool:" << HasMemFunc<Con>::value << std::endl;std::unique_lock lock(this->mu_);if constexpr (HasMemFunc<Con>::value) {T t = this->queue_.front();this->queue_.pop_front();return t;}}T PopBack() {std::cout << "PopBack bool:" << has_member_pop_back<Con>::value << std::endl;if constexpr (hasmem_pop_back<Con>::value) {std::unique_lock lock(this->mu_);T t = this->queue_.back();this->queue_.pop_back();return t;}}private:std::mutex mu_;Con queue_;
};

上面的代码主动对三部分进行了处理,一部分是增加了类本身不允许拷贝;另外一个增加了对容器的再次抽象,即容器可以动态传入;第三部分就是增加了对容器的成员函数通过SFINAE进行了判断。这也是模板技术在实际场景中应用的一种方式,下面会对其进行分析。需要注意的是,这里使用的c++17以上的编译环境。下面看一下相关的代码:

#ifndef __COMMON_H__
#define __COMMON_H__#include <functional>
#include <utility>
using CallBackMsg = std::function<void(int *, int)>;
using Task = std::function<void(int)>;class NoCopy {
protected:NoCopy() = default;~NoCopy() = default;public:NoCopy(const NoCopy &) = delete;NoCopy &operator=(const NoCopy &) = delete;NoCopy(NoCopy &&) = delete;NoCopy &operator=(NoCopy &&) = delete;
};
//第一种方式
template <typename T> struct HasMemFunc {
private:template <typename U> static auto Check(int) -> decltype(std::declval<U>().pop_front(), std::true_type());template <typename U> static std::false_type Check(...);public:enum { value = std::is_same<decltype(Check<T>(0)), std::true_type>::value };
};//Muduo库的使用方式(和上面类似):
template <typename T> struct hasPopFront {template <typename C> static char Check(decltype(&C::pop_front));template <typename C> static int32_t Check(...);const static bool value = sizeof(Check<T>(0)) == 1;
};//第二种方式
template <typename T> using Type = void;//处理无参
template <typename T, typename V = void> struct HasPop : std::false_type {};
template <typename T> struct HasPop<T, Type<decltype(std::declval<T>().pop_front())>> : std::true_type {};
//第二种方式-c++11后
template <typename T, typename V = void> struct HasMemFuncCpp11 : std::false_type {};template <typename T>
struct HasMemFuncCpp11<T, Type<decltype(std::declval<T>().emplace_back(std::declval<typename T::value_type>()))>>: std::true_type {};//第三种方式
#define HAS_MEM(mem)                                                                                             \template <typename T, typename... Args> struct hasmem_##mem {                                                 \private:                                                                                                             \template <typename U>                                                                                              \static auto Check(int) -> decltype(std::declval<U>().mem(std::declval<Args>()...), std::true_type());           \template <typename U> static std::false_type Check(...);                                                           \\public:                                                                                                              \enum { value = std::is_same<decltype(Check<T>(0)), std::true_type>::value };                                       \};
HAS_MEM(pop)
HAS_MEM(pop_back)
HAS_MEM(push)
#endif // __COMMON_H__

在上面代码中主要分成了三种形式,第一种和第二种是使用检查函数是否存在的普通方式,虽然看上去是使用了模板,但对成员函数名称还是进行了限制。所以如果需要限制多种成员函数还得手动写多个类;第三种使用宏的方式自动产生相关的模板代码,这样会少写不少的重复的类似的代码。
这三种SFINAE的原理基本是一致的,虽然实现的手段有细节的不同。但都是通过decltype和std::declval(二者的区别可以查看前面的相关文章),通过是否能够符合模板自动匹配(即能否正常产生相关特化模板)来返回true 或false的value来达到判断是否存在函数的目的,然后通过if constexpr在编译期进行处理。Muduo库的使用方式前面分析过(“SFINAE的技巧应用”),基本原理也是如此,只是直接使用定义的函数匹配来得到值而非使用std::true_type这种形式,但逻辑是一样的。
至于是否使用 std::is_same_v来替代 std::is_same,就看个人的兴趣了。
大家分析的时候儿可以从第一种开始,简单的按分析说明一对就明白了,然后再到第二种,特别是Type类型能否获取,是value值的关键。到第三种基本就是前面的抽象版,理解了前面的两种方式,第三种就非常简单了。
此处的封装未必是要求把所有的容器都封装起来,但它可以适应所有容器,什么意思呢?开发者可以根据自己的情况来选取指定的一两种容器来使用。当然,在实际的应用场景中,可能更多的是直接使用容器。这里之所以封装起来,就是为了给出一个更搞抽象的思路和方法。这点对于自己写容器而不使用STL中的容器的情况下更有意义。
随着GCC等编译器对c++20支持的逐渐普及化。估计明后年,可能就可以普遍的使用c++20编程了(ubuntu22默认的g++11对c++20已经支持了大部分),这样就可以使用Concept以及其它相关的新特性,开发工作会变得更简单一些。

五、总结

在分析完成数据结构的封装后,基本也就明白了在多线程中如何使用STL中的容器。但是,一般对线程安全的操作控制,都是使用锁。不管锁的粒度是大是小,对性能的影响一般来说都是比较大的。而多线程特别是线程池恰恰又都是在高性能的场景下应用,所以这时就需要开发者认真考虑加锁引起的性能损失。
当然,在后面可以考虑在某些情况下使用无锁编程技术,让数据的处理更快捷。但无锁编程也不是万能的,它也是有其相对的应用场景。万流归宗,还是需要开发者对整体技术的把握和实际应用场景进行综合考虑。

http://www.yayakq.cn/news/558864/

相关文章:

  • 重庆网站建设公司 夹夹虫好小米的网络营销方式
  • 宁德城乡建设网站网站美工用什么软件
  • 找人做网站需要什么软件做网站和做网页的区别
  • 全国域名备案查询泰安seo
  • 电子商务的网站开发的工作内容秦皇岛海三建设没钱了
  • 网站做支付系统猪八戒网站怎么做任务
  • 代码统计网站网站搭建方案模板
  • 推荐企业手机网站建设asp源码下载
  • h5自适应网站建设是什么意思wordpress 媒体 路径
  • 网站建设的定位是什么意思百度推广 网站备案
  • 网站建设优化哪家公司好最新新闻热点事件国际
  • 郑州市做网站公司a汉狮路由器通过域名解析做网站
  • 关于中国幼教网站开发的经验做网站是什么公司
  • 微信官方版官方网站wordpress 中文附件
  • 项目网站开发js放的位置网站建设 教学大纲
  • 网站建设在商标第几类网站建设内页
  • 广州手机网站开发报价重庆传媒公司前十名
  • php网站开发设计系统泰州东方医院男科
  • 荆门住房建设厅网站重庆铜梁网站建设报价
  • 怎么做阿里巴巴英文网站公众号制作模板app
  • 防疫网站网页设计付费网站搭建
  • 注册一个做网站的公司好海南网站建设推广
  • 怎么在工商局网站查公司必应搜索引擎怎么样
  • 南沙区建设局网站扁平化的网站有哪些
  • 佛山做网站推广的公司阿里云WordPress一键安装
  • 网站建设明细建设品牌公司网站
  • 兴化网站建设价格全球搜索引擎排名2022
  • 做蛋糕视频的网站中小企业网站建设与推广分析
  • 濮阳做网站的电话理论网
  • seo怎么优化软件seo关键词排名优化销售