C++实现一个简易的线程池
生活随笔
收集整理的這篇文章主要介紹了
C++实现一个简易的线程池
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 線程池的概念
- 什么是線程池
- 線程池的優點
- 線程池的應用場景
- 線程池的實現
- 實現思路
- 代碼實現
線程池的概念
什么是線程池
顧名思義,線程池就是一個有很多空閑線程的池子(線程的數量受到限制),需要用到多執行流進行任務處理時,就從池子中喚醒一個線程去處理任務
線程池的優點
- 避免大量線程頻繁創建和銷毀帶來的時間成本
:如果在一開始即創建好線程,要用的時候直接從線程池中取出,用完再放回,這樣就大大減少了創建與銷毀帶來的時間成本 - 避免無限制的線程創建導致資源耗盡
:線程池限制了線程的數量,這樣就保證了不會因為線程創建過多導致資源耗竭,程序崩潰的情況
線程池的應用場景
有大量的數據處理請求,需要多執行流并發/并行處理
線程池的實現
實現思路
首先線程池的核心,就是大量的線程和一個任務緩沖隊列。在線程池創建時就提前創建好一定數量的線程,如果有任務到來則將任務放入緩沖隊列中,此時喚醒線程池中的線程取出任務進行處理,如果線程池沒有空閑線程,則阻塞任務,直到有線程處理完任務回歸線程池中。同時,因為不同任務有不同的處理方法,所以要開放接口給外界,處理的數據和方法由外界自己定,線程池只負責調用對應的任務處理方法進行處理,不關心其中的內容。這樣就更具有靈活性。
代碼實現
下面就來實現一個線程池,具體的細節都有注釋
#include<iostream> #include<pthread.h> #include<cstdlib> #include<queue>//類型重命名,將處理的方法定義為一個函數指針 typedef void (*handler_t)(int);const size_t MAX_SIZE = 10;//任務 class ThreadTask {public://設置需要處理的數據與對應的處理方法void SetTask(int data, handler_t handler){_data = data;_handler = handler;}//處理數據void Run(){_handler(_data);}private:int _data;handler_t _handler; };//線程池 class ThreadPool {public:ThreadPool(size_t capacity = MAX_SIZE) : _capacity(capacity){pthread_cond_init(&_cond, NULL);pthread_mutex_init(&_mutex, NULL);//線程池提前創建線程for(size_t i = 0; i < _capacity; i++){pthread_t pid;int ret = pthread_create(&pid, NULL, start_routine, this);if(ret){std::cout << "線程創建失敗" << std::endl;exit(-1);}}}~ThreadPool(){pthread_cond_destroy(&_cond);pthread_mutex_destroy(&_mutex);}void Push(ThreadTask& Task){//互斥鎖保證線程安全pthread_mutex_lock(&_mutex);//將任務放入隊列中_queue.push(Task);pthread_mutex_unlock(&_mutex);//喚醒線程池全部線程,誰搶到誰就來處理這個任務pthread_cond_broadcast(&_cond);}//入口函數的參數只能有一個void*,所以需要寫為static函數來去掉隱含的this指針static void* start_routine(void *arg){//將void*強轉為需要的類型ThreadPool* pool = (ThreadPool*)arg;while(1){pthread_mutex_lock(&pool->_mutex); //如果任務隊列為空則使線程循環等待while(pool->_queue.empty()){pthread_cond_wait(&pool->_cond, &pool->_mutex);}ThreadTask Task;//將任務出隊進行處理Task = pool->_queue.front();pool->_queue.pop();pthread_mutex_unlock(&pool->_mutex);//解鎖后再處理,因為加鎖只是保證隊列操作的安全性Task.Run();}return NULL;}private://互斥鎖保證線程安全,條件變量保證任務的提交與處理同步pthread_cond_t _cond;pthread_mutex_t _mutex;size_t _capacity;std::queue<ThreadTask> _queue; };下面寫一個函數來測試一下
#include "ThreadPool.hpp" #include<unistd.h>void handler1(int data) {std::cout << "線程ID:"<< pthread_self() <<" 處理奇數數據:" << data << std::endl;sleep(1); }void handler2(int data) {std::cout << "線程ID:"<< pthread_self() <<" 處理偶數數據:" << data << std::endl;sleep(1); }int main() {ThreadPool pool;for(int i = 0; i < 10; i++){ThreadTask task;//分別處理奇數和偶數if(i & 1){task.SetTask(i, handler1);}else{task.SetTask(i, handler2); }//任務放入隊列中pool.Push(task);}//休眠一段時間防止結束后主線程退出sleep(100);return 0; }使用兩種不同的處理方法來分別處理0-9的奇偶數
運行截圖
總結
以上是生活随笔為你收集整理的C++实现一个简易的线程池的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++ STL : 模拟实现STL中的s
- 下一篇: C++ STL : 模拟实现STL中的v