什么是線程池
處理大量並發任務,一個請求一個線程來處理請求任務,大量的線程創建和銷毀將過多的消耗系統資源,還增加了線程上下文切換開銷。
線程池通過在系統中預先創建一定數量的線程,當任務請求到來時從線程池中分配一個預先創建的線程去處理任務,線程在處理任務之后還可以重用,不用銷毀,從而節省系統資源。對於多核處理器,線程會被分配到多個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來使每個調用中的線程結束