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