赞
踩
目录
创建一个线程,就是要这个线程去完成某种任务的。
池化技术就是,提前创建一批线程,有任务这一批线程就会执行。而不是有任务的时候在去创建线程。
池化技术有着更高的效率,因为线程都是提前创建好的,直接执行任务。
懒汉和饿汉模式是一种设计模式
懒汉模式:
例:进程需要一块内存资源,什么时候真正用到了这块内存时,我在去创建而不是提前创建。
这种模式的优点就是,启动的更快,程序启动时,数据要加载到内存,懒汉就是延时加载,用的时候在加载。
就是某一些类,就应该只有一个对象,不应该有多个。
线程池就是这样的,创建两个线程池也没有意义,可以多创建几个线程。
实现方法
将类的构造函数进行私有,这样就无法在创建对象了。
在类中提供一个共有的静态方法,这个方法可以初始化和获取线程池。
这个没什么难度,就是字符串的拼接,可能需要注意的就是可变参数的使用。
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
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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。