欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > LINUX:懒汉单例模式线程池

LINUX:懒汉单例模式线程池

2024/10/25 2:27:45 来源:https://blog.csdn.net/W2155/article/details/140463164  浏览:    关键词:LINUX:懒汉单例模式线程池

目录

1.什么是线程池,线程池的优势

2.懒汉和饿汉模式

3.单例模式

4.日志系统

5.线程池


1.什么是线程池,线程池的优势

创建一个线程,就是要这个线程去完成某种任务的。

池化技术就是,提前创建一批线程,有任务这一批线程就会执行。而不是有任务的时候在去创建线程。

池化技术有着更高的效率,因为线程都是提前创建好的,直接执行任务。

2.懒汉和饿汉模式

懒汉和饿汉模式是一种设计模式

懒汉模式:

例:进程需要一块内存资源,什么时候真正用到了这块内存时,我在去创建而不是提前创建。

这种模式的优点就是,启动的更快,程序启动时,数据要加载到内存,懒汉就是延时加载,用的时候在加载。

3.单例模式

就是某一些类,就应该只有一个对象,不应该有多个。

线程池就是这样的,创建两个线程池也没有意义,可以多创建几个线程。

实现方法

将类的构造函数进行私有,这样就无法在创建对象了。

在类中提供一个共有的静态方法,这个方法可以初始化和获取线程池。

4.日志系统

这个没什么难度,就是字符串的拼接,可能需要注意的就是可变参数的使用。

log.hpp


#ifndef __LOG_HPP__
#define __LOG_HPP__
#include <iostream>
#include <string>
#include <time.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdarg.h>
#include <fstream>
// 日志等级enum loglevel{Debug = 0,Info,Warning,Error,FATAL,};
namespace lg
{bool isSave = false; //是否保存到文件std::string savefile = "log.txt";//保存的文件名std::string LeveltoString(int level) //将日志等级转化为字符串{switch (level){case Debug:return "Debug";case Info:return "Info";case Warning:return "Warning";case Error:return "Error";case FATAL:return "FATAL";default:return "Unknown";}}std::string TimetoString() //将时间转化为字符串{time_t cur_time = time(nullptr);tm *formattime = localtime(&cur_time);return std::string(std::to_string(formattime->tm_year + 1900) + "/" + std::to_string(formattime->tm_mon + 1) + "/" + std::to_string(formattime->tm_mday) + " " + std::to_string(formattime->tm_hour + 1) + ":" + std::to_string(formattime->tm_min + 1));}std::string PidtoString()//将pid转化为字符串{return std::to_string(getpid());}void SavetoFile(std::string &message)//保存到文件{std::ofstream out(savefile, std::ios::app);if (!out.is_open()){return;}out << message << std::endl;out.close();}pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;// 日志的格式: 日志等级 + 日志时间 + 代码文件名 + 行数 + 日志内容void LogMessage(std::string filename, int linenum, int level, const char *formate, ...){std::string levelstring = LeveltoString(level);std::string timestring = TimetoString();std::string pidstring = PidtoString();//是对可变参数的解析char buffer[1024];va_list ap;va_start(ap, formate);vsnprintf(buffer, sizeof(buffer), formate, ap);va_end(ap);std::string contentstring = move(std::string(buffer));std::string message = "[" + levelstring + "]" + "[" + timestring + "]" + "[" + filename + "]" + "[" + std::to_string(linenum) + "]" + "[" + pidstring + "]" + "[" + contentstring + "]";if (!isSave){pthread_mutex_lock(&mutex);std::cout << message << std::endl;pthread_mutex_unlock(&mutex);}else{SavetoFile(message);}}#define Log(level, format, ...)                                                \do                                                                         \{                                                                          \LogMessage(__FILE__, __LINE__, level, format, ##__VA_ARGS__); \} while (0)#define save()         \do                 \{                  \isSave = true; \} while (0);#define print()        \do                 \{                  \isSave = false; \} while (0);
}#endif

5.线程池

threadpool.hpp

#ifndef __THREADPOOL__
#define __THREADPOOL__#include <iostream>
#include <pthread.h>
#include <thread>
#include <unistd.h>
#include <queue>
#include <semaphore.h>
#include "log.hpp"
#include <functional>// 创建出一批线程,从任务队列里拿任务namespace mtp
{using namespace lg;using namespace std::placeholders;int _default = 3;template <class T>class threadpool{private:threadpool(int threadnum = _default): _threadnum(threadnum){pthread_mutex_init(&_mutex, nullptr);pthread_cond_init(&_cond, nullptr);Log(Info, "Construct threadpool");}// 线程的回调方法void handlertask(std::string name){while (true){pthread_mutex_lock(&_mutex);// 线程池运行 任务队列为空时while (_isrunning && _taskqueue.empty()){_waitnum++;pthread_cond_wait(&_cond, &_mutex);_waitnum--;}// 线程池不运行 任务队列为空if (!_isrunning && _taskqueue.empty()){pthread_mutex_unlock(&_mutex);break;}// 线程池运行 队列不为空// 线程池不运行 队列不为空T t = _taskqueue.front();_taskqueue.pop();pthread_mutex_unlock(&_mutex);t(name); // 执行任务// std::cout<<"handler" << t <<std::endl;}}// 创建线程void Init(){for (int i = 0; i < _threadnum; i++){std::string name = "thread" + std::to_string(i);_threads.emplace_back(std::bind(&threadpool::handlertask, this, _1), name);Log(Info, "create %s", name.c_str());}}~threadpool(){pthread_mutex_destroy(&_mutex);pthread_cond_destroy(&_cond);Log(Info, "threadpool destory");}// 禁止拷贝threadpool<T> &operator=(const threadpool<T> &) = delete;threadpool(const threadpool<T> &) = delete;public:// 执行单例模式static threadpool<T>* getInstance(){if (_instance == nullptr)//加上这个if语句,如果是获取线程池,就不用获取锁了{// 初始化线程池pthread_mutex_lock(&_lock);//只有第一次线程创建时才会进,无论创建还是获取都要返回 一个线程池的指针if (_instance == nullptr){_instance = new threadpool<T>;_instance->Init();Log(Info, "Init threadpool");}pthread_mutex_unlock(&_lock);}Log(Info, "get threadpool");return _instance;}void stop(){pthread_mutex_lock(&_mutex);_isrunning = false;pthread_mutex_unlock(&_mutex);pthread_cond_broadcast(&_cond);}void waitall(){for (auto &thread : _threads){thread.join();}Log(Info, "Wait Sucess");}void enqueue(T t){pthread_mutex_lock(&_mutex);if (_isrunning){_taskqueue.push(t);Log(Info, "push task sucess");if (_waitnum > 0){pthread_cond_signal(&_cond);}}pthread_mutex_unlock(&_mutex);}private:int _threadnum;std::vector<std::thread> _threads;std::queue<T> _taskqueue; // 任务队列pthread_mutex_t _mutex;pthread_cond_t _cond;bool _isrunning = true; // 是否运行int _waitnum = 0;       // d等待的线程数// 添加单例模式static threadpool<T> *_instance;static pthread_mutex_t _lock; // 为了保证单例模式的线程安全};template <class T>threadpool<T> *threadpool<T>::_instance = nullptr;template <class T>pthread_mutex_t threadpool<T>::_lock = PTHREAD_MUTEX_INITIALIZER;
}#endif

Task.hpp

#ifndef __task_HPP__
#define __task_HPP__#include<string>
#include<stdlib.h>
#include<time.h>
#include<iostream>
class Task
{
public:
Task(std::string taskname)
:_taskname(taskname)
{}void operator()(std::string name)
{sleep(1);std::cout << name <<"Excute "<< _taskname << std::endl;
}private:std::string _taskname;
};#endif

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com