什么是线程池
处理大量并发任务,一个请求一个线程来处理请求任务,大量的线程创建和销毁将过多的消耗系统资源,还增加了线程上下文切换开销。
线程池通过在系统中预先创建一定数量的线程,当任务请求到来时从线程池中分配一个预先创建的线程去处理任务,线程在处理任务之后还可以重用,不用销毁,从而节省系统资源。对于多核处理器,线程会被分配到多个CPU,提高并行处理效率。每个线程独立阻塞,防止主线程被阻塞而使主流程被阻塞
半同步半异步线程池
三层
第一层:同步服务层,处理上层任务请求
第二层:同步排队层,上层的任务请求放到同步排队层中等待处理(同步队列)
第三层:异步服务层,多个线程同时处理排队层中的任务,从同步排队层取出任务并处理
线程池有两个活动过程
一个是往同步队列中添加任务过程
一个是从同步队列中取任务过程
实现
《深入应用C++11》有完整的代码,但是用到的C11技术很多——锁,条件变量,move,不好记,大体讲一下思路
需要实现两个类,一个类用于实现同步队列(SyncQueue类),另一个类用于实现线程池(ThreadPool)
SyncQueue类
同步队列类完全可以用生产者消费者代替,书上代码用的条件变量实现的同步队列,这个类有个六个成员变量:
缓冲区用list:template<typename T> std::list<T> m_queue
互斥变量:std::mutex m_mutex
两个条件变量或者两个信号量,full和empty
同步队列最大size:int m_maxsize
停止标志:bool m_needstop
成员函数:
Take函数:取任务,P(full) mutex.lock mutex.unlock V(empty)
Add函数: P(empty) mutex.lock mutex.unlock V(full)
Stop函数
ThreadPool类
ThreadPool类有三个成员变量:
线程组:std::list<std::shared_ptr<std::thread>> m_threadgroup
同步队列: SyncQueue<Task> m_queue
停止线程池:bool m_running
成员函数:
Start:一个任务是创建线程放到线程组里,并取任务执行m_queue.Take
Stop:让同步队列中的线程停止,m_running = false 另外用thread.join来使每个调用中的线程结束