谈线程池之前先讲一讲池化技术
池化技术指的是提前准备一些资源,在需要时可以重复使用这些预先准备的资源。
常见的池化技术:线程池、进程池、内存池。
池化技术的优点
不同池化技术的应用场景不同,但都有一些共同的特点
1、资源的重复利用
2、降低系统的开销
例如,线程池预先创建一批线程,在IO密集型的场景下,线程池可以有效的降低频繁的创建线程释放线程的开销。内存池预先向系统申请一大块内存,通过自行设计方法管理内存,可以有效的减少内存碎片的问题。
池化技术简单点来说,就是提前保存大量的资源,以备不时之需。池化技术有两个特点,提前创建和重复利用。
预先创建一批线程,提高处理业务的效率。
通过指派任务的方式,不用从零开始创建,直接把某个任务指派到某个线程。
线程池通过一个线程安全的阻塞任务队列加上一个或一个以上的线程实现,线程池中的线程可以从阻塞队列中获取任务进行任务处理,当线程都处于繁忙状态时可以将任务加入阻塞队列中,等到其它的线程空闲后进行处理。
解决的问题
1、节省创建系统的时间成本的问题
2、防止系统大量请求的冲击,将大量请求塞到任务队列里,这样不用创建过多执行流导致系统震荡的问题例如网络服务器请求。
模拟实现
所需的参数:互斥量pthread_mutex_t,条件变量pthread_cond_wait,和任务队列queue。
- #include <iostream>
- #include <pthread.h>
- #include <queue>
-
- class Task{
- private:
- int num;
- public:
- Task(int _num)
- :num(_num)
- {}
- void run()
- {
- std::cout<<"thread id is "<<pthread_self()<<",Get num is "<<num<<std::endl;
- }
- };
-
- class ThreadPool
- {
- private:
- pthread_mutex_t mtx;//互斥量
- pthread_cond_t cond;//条件变量
- std::queue<Task*> qt;//任务队列
- int thread_num;//线程池中线程的数量
- public:
- ThreadPool(int _thread_num)
- :thread_num(_thread_num)
- {}
- void ThreadPoolInit()
- {
- //初始化线程池
- pthread_mutex_init(&mtx,nullptr);
- pthread_cond_init(&cond,nullptr);
- //预先创建一批线程
- pthread_t tid[thread_num];
- for(int i=0;i < thread_num;i++)
- {
- pthread_create(tid+i,nullptr,routine,this);//将this指针作为参数传入入口函数
- }
- }
- void PushTask(Task* t)
- {
- Lock();//加锁
- qt.push(t);
- UnLock();
- WakeUp();//一旦有任务,就唤醒线程
- }
- private:
- //线程的入口函数
- static void* routine(void* arg)
- {
- ThreadPool* tp = (ThreadPool*)arg;
- while(true)
- {
- tp->Lock();//加锁
- while(tp->qt.empty())//while判断条件是否满足,防止虚唤醒
- {
- tp->Wait();
- }
- Task* t = tp->qt.front();
- tp->qt.pop();
- tp->UnLock();
- t->run();
- }
- return nullptr;
- }
- //封装一些函数
- void Lock()
- {
- pthread_mutex_lock(&mtx);
- }
- void UnLock()
- {
- pthread_mutex_unlock(&mtx);
- }
- void Wait()
- {
- pthread_cond_wait(&cond,&mtx);
- }
- void WakeUp()
- {
- pthread_cond_signal(&cond);
- }
-
- };
