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