文章目录
原理
如我们每次动态开辟一个变量空间的时候,都会有效率的损失,如果有一个内存池,需要的化直接在里面取就行了,这就大大的提高了效率
当我们创建任务的时候再去申请线程,就相当于我们需要malloc的时候再去申请空间,创建线程也是有成本的,
请求来了,线程要提前准备好,任务来了,就指派给他
提前准备好的线程,原来随时处理任务就叫做线程池
(提高效率)
实现
Task.hpp
使用这个Task类,将此作为里面的类型
Task.hpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| #pragma once #include <iostream> #include <pthread.h>
namespace ns_task
{ class Task { private: int _x; int _y; char _op; public: Task() { } Task(int x, int y, char op) : _x(x), _y(y), _op(op) { } ~Task() { } int Run() { int res = 0; switch (_op) { case '+': res = _x + _y; break; case '-': res = _x - _y; break; case '*': res = _x * _y; break; case '/': res = _x / _y; break; case '%': res = _x % _y; break; default: std::cout << "bug?" << std::endl; break; } std::cout << "当前任务正在被:" << pthread_self() << "处理:" << _x << _op << _y << "=" << res << std::endl; return res; } Task operator=(Task &s) { if (this != &s) { _x = s._x; _y = s._y; _op = s._op; } return *this; } int operator()() { return Run(); } }; }
|
threadpool.hpp
实现线程池类,高封装性,将所有的对于线程的操作都放在这个类里面是实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
| #pragma once #include <iostream> #include <string> #include <queue> #include<unistd.h> #include<pthread.h>
namespace ns_threadpool { const int g_num=5; template <class T> class ThreadPool {
private: int num_; std::queue<T> task_queue_; pthread_mutex_t mtx_; pthread_cond_t cond_;
public: ThreadPool(int num=g_num) :num_(num) { pthread_mutex_init(&mtx_,nullptr); pthread_cond_init(&cond_,nullptr); } ~ThreadPool() { pthread_mutex_destroy(&mtx_); pthread_cond_destroy(&cond_); }
static void* Rountine(void* args) {
pthread_detach(pthread_self()); ThreadPool<T>* tp=(ThreadPool<T>*)args; while(true) {
tp->Lock(); while(tp->IsEmpty()) { tp->Wait(); } T t; tp->PopTask(&t); tp->UnLock(); t.Run();
sleep(1); } }
void InitThreadPool() { pthread_t tid; for(int i=0;i<num_;i++) { pthread_create(&tid,nullptr,Rountine,(void*)this); } } void PopTask(T* out) { *out=task_queue_.front(); task_queue_.pop(); } void Wait() { pthread_cond_wait(&cond_,&mtx_); } bool IsEmpty() { return task_queue_.empty(); } void Lock() { pthread_mutex_lock(&mtx_); } void UnLock() { pthread_mutex_unlock(&mtx_); } void Wakeup() { pthread_cond_signal(&cond_); } void PushTask(const T & in) { Lock(); task_queue_.push(in); UnLock(); Wakeup(); }
}; }
|
main.cc
非单例模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #include"threadpool.hpp" #include"Task.hpp" #include<unistd.h> #include<cstdlib> #include<ctime> using namespace ns_task; using namespace ns_threadpool;
int main() { ThreadPool<Task>* tp=new ThreadPool<Task>(); tp->InitThreadPool(); srand((long long)time(nullptr)); while(true) {
Task t(rand()%20+1,rand()%10+1,"+-*/%"[rand()%5]); tp->PushTask(t);
}
return 0; }
|
详细代码可以查看
ThreadPool