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

单例 C++ 懒汉+恶汉

单例设计模式是一种创建型设计模式,确保一个类只有一个实例,减少了内存的开销,并提供一个全局访问点访问该实例。 私有化构造函数、拷贝构造函数、赋值函数 ,定义一个类的私有静态对象成员,定义一个公共的访问该实例静态对象成员的方法,返回该静态对象成员 ,单例设计模式 有懒汉式:获取该类的对象时才创建该类的实例(局部静态变量解决线程不安全),还有饿汉式:获取前就已经创建好。单例模式一般没有接口,扩展困难。

#include <iostream>
#include <vector>
#include <thread>
#include <queue>
#include <functional>
#include <mutex>
#include <condition_variable>
#include <chrono>
class ThreadPool {
private:std::vector<std::thread> threads;std::queue<std::function<void()>> tasks;std::mutex mutex;std::condition_variable condition;bool stop;ThreadPool() : stop(false) {int numThreads = std::thread::hardware_concurrency(); //来获取当前系统支持的并发线程数量,在多线程编程中,可以使用这个值来确定最佳的线程数量以提高程序的性能。for (int i = 0; i < numThreads; ++i) {threads.emplace_back([this] {while (true) {std::unique_lock<std::mutex> lock(mutex);condition.wait(lock, [this] { return stop || !tasks.empty(); });if (stop && tasks.empty()) {return; }std::function<void()> task=std::move(tasks.front());tasks.pop();lock.unlock();//确保只有一个线程共享资源,这个资源以及取出来了,就可以解锁让其他线程去访问了task();}           });      } }ThreadPool(const ThreadPool& theadpool) = delete;
ThreadPool& operator=(const ThreadPool& theadpoll) = delete;
/*MprpcApplication(const MprpcApplication&) = delete;
MprpcApplication(MprpcApplication&&) = delete;
还有这种写法*/
//析构函数是私有的时候,只有类的成员函数才能调用析构函数public: 
~ThreadPool() {{std::unique_lock<std::mutex> lock(mutex);stop = true;}condition.notify_all();for (auto& thread : threads) {thread.join();}  }static ThreadPool& getInstance() {使用引用避免拷贝构造//懒汉模式需要解决线程不安全//使用C++11的call_once实现线程安全,避免多个线程进来的时候同时new
//多线程运行的结果的单线程运行的结果一样,但是call_once只能在多线程里面使用,在main()里面调用会报错,像主函数thread t1什么的那样的可以//也使用两个 if 判断语句的技术称为双检锁;好处是,只有判断指针为空的时候才加锁//最好的是使用局部静态变量来解决static ThreadPool instance; 在 C++11 中,静态局部变量这种方式天然是线程安全的
这里不能定义为引用,引用是引用已经存在的对象return instance;/*
;饿汉模式,线程安全, */ }// 向任务队列中添加任务template<typename F, typename... Args>//任意数量,类型的参数void enqueue(F&& f, Args&&... args) {可变参数模板// 将各种类型的任务包装为std::function,然后加入任务队列,std::function<void()> task=std::bind(std::forward<F>(f), std::forward<Args>(args)...);{std::unique_lock<std::mutex> lock(mutex);tasks.emplace(std::move(task));}condition.notify_one(); // 通知一个等待的线程去执行任务}};
int main() {// ThreadPool::getInstance(); // 获取线程池实例for (int i = 0; i < 8; ++i) {ThreadPool::getInstance().enqueue([i] {
std::cout << "Task " << i << " is running in thread  " << std::this_thread::get_id() << std::endl;std::this_thread::sleep_for(std::chrono::seconds(5));std::cout << "Task " << i << " is done " << std::endl;}); }  
return 0;}
饿汉:
class Singleton{public:static Singleton* GetInstance() //通过调用GetInstance() 在类外获得实例{	return &_slt;                //返回这个实例的地址} private:static Singleton _slt; //类内声明


http://www.mrgr.cn/news/62376.html

相关文章:

  • 使用Go构建以太坊
  • @AutoWired和 @Resource原理深度分析!
  • Flutter Web部署到子路径的打包指令
  • 程序员修仙传
  • 轮询系统升级完成
  • 【 C++ 】C++11的初步学习
  • 前端面试题21 | 了解过媒体查询吗?它有哪些应用场景?
  • 《JVM第4课》程序计数器
  • 注册信息的提交
  • 不适合的学习方法
  • (5)数组
  • 【SAP FICO】八大业务_6货币资金管理
  • 数据采集-Kepware OPCUA 服务器实现
  • CNN在线识别手写中文
  • 返回数组中元素的数据类型numpy.dtype.name
  • 四季皆宜的网球场:气膜网球馆改造方案—轻空间
  • 刘艳兵-DBA016-在您的数据库中,SALES表存在于SH用户中,并且启用了统一审计。作为DBA,您成功执行了以下指令:
  • Spring Boot 配置文件详解与最佳实践
  • 第15天预编译
  • 组合两个表
  • 计算机组成原理之选择结构语句的机器级别表示
  • HTTPS对中间人真就束手就擒了?
  • NFT、加密货币和区块链将如何在某一天共同推动Web3
  • 基于 ThinkPHP+Mysql灵活用工_灵活用工系统_灵活用工平台
  • 什么样的工程项目管理软件适合中小施工企业?
  • 最小期望风险估计