# ThreadPool **Repository Path**: hjq8051/ThreadPool ## Basic Information - **Project Name**: ThreadPool - **Description**: c++线程池:基于c++11实现、 提供执行链(任务间共享数据无须显式加锁)。支持任务类型:函数指针、仿函数、lambda、函数对象。任务管控方式:使用std::future进行管控、设置任务完成时的回调 - **Primary Language**: C++ - **License**: GPL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 8 - **Created**: 2024-11-28 - **Last Updated**: 2024-11-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ThreadPool #### 介绍 线程池类型:基于c++11实现、带优先级、固定线程数、执行链(共享数据无需显式加锁) 任务提交方式:提供函数指针、仿函数、lambda、函数对象作为参数向线程池提交任务的方法。 任务管控方式:使用std::future进行管控、设置任务完成时的回调 #### 使用说明 1.获取线程池实例: ``` hzw::ThreadPool& threadPool{ hzw::ThreadPool::get_instance() };//设置线程池为:释放时保证所有任务完成,线程数为cpu核心数 auto& threadPool{ hzw::ThreadPool::get_instance(true, 10) };//设置线程池为:释放时保证所有任务完成,线程数为10 auto& threadPool{ hzw::ThreadPool::get_instance(false) };//设置线程池为:释放时不保证所有任务完成 ``` ``` //保证task全部执行完成 #include "ThreadPool.h" #include #define TASK_COUNT 10 std::mutex m; void task(int i) { m.lock(); std::cout << i; m.unlock(); } int main(int argc, char* argv[]) { auto& threadPool{ hzw::ThreadPool::get_instance(true) }; for (int i{ 0 }; i < TASK_COUNT; ++i) threadPool.push_task(task, i); } ``` ![保证task全部执行完成](https://images.gitee.com/uploads/images/2019/0602/211155_fedf4f56_5038916.png "CompleteAllTask_T.png") ``` //不保证task全部执行完成 //此示例主线程结束快于线程池任务执行,固线程池直接释放无一个任务被执行 #include "ThreadPool.h" #include #define TASK_COUNT 10 std::mutex m; void task(int i) { m.lock(); std::cout << i; m.unlock(); } int main(int argc, char* argv[]) { auto& threadPool{ hzw::ThreadPool::get_instance(false) }; for (int i{ 0 }; i < TASK_COUNT; ++i) threadPool.push_task(task, i); } ``` ![不保证task全部执行完成](https://images.gitee.com/uploads/images/2019/0602/211319_51d7c47e_5038916.png "CompleteAllTask_F.png") 2.向线程池提交任务: (1)普通函数: ``` void fun(param...){...} threadPool.push_task(fun, param...);//默认优先级 threadPool.push_task(hzw::ThreadPool::HIG, fun, param...);//带优先级 ``` (2)lambda: ``` threadPool.push_task([] {...});//默认优先级 threadPool.push_task(hzw::ThreadPool::MID, [] {...});//带优先级 ``` (3)std::function: ``` std::function fun{[]{...}}; threadPool.push_task(fun);//默认优先级 threadPool.push_task(hzw::ThreadPool::LOW, fun);//带优先级 ``` (4)仿函数: ``` struct Fun{void operator()(){...}}; threadPool.push_task(Fun{}); ``` (5)回调方式: ``` void callback(param){...} param task(){...} threadPool.push_task_c(callback, task); ``` (6)总述:[]代表可选 `push_task([优先级], [执行链], 任务,任务参数)` `push_task_c([优先级], [执行链], 回调,任务,任务参数)` 3.获取任务结果和同步: ``` int fun(){...} std::future result{threadPool.push_task(fun)}; result.get();//阻塞调用线程直到fun()被线程池执行完成 ``` 4.执行链(Chain) (1)不使用执行链可能写法 ``` std::mutex m;//保证输出有序 #define TEST_COUNT 100 void testChain_1() { for (int i{ 0 }; i < TEST_COUNT; ++i) { m.lock(); std::cout << i << std::endl; m.unlock(); } } void testChain_2() { for (int i{ 0 }; i < TEST_COUNT; ++i) { m.lock(); std::cout << i << std::endl; m.unlock(); } } int main(int argc, char* argv[]) { auto& threadPool{ ThreadPool::get_instance(true, 2) };//获取线程池实例 threadPool.push_task(testChain_1); threadPool.push_task(testChain_2); } ``` (2)使用执行链,将两个方法并为一条执行链(输出将有序)无需使用锁显式同步 ``` #define TEST_COUNT 100 void testChain_1() { for (int i{ 0 }; i < TEST_COUNT; ++i) std::cout << i << std::endl; } void testChain_2() { for (int i{ 0 }; i < TEST_COUNT; ++i) std::cout << i << std::endl; } int main(int argc, char* argv[]) { auto& threadPool{ ThreadPool::get_instance(true, 2) };//获取线程池实例 ThreadPool::Chain chain;//创建执行链 //将testChain_1和testChain_2任务并入一条执行链 threadPool.push_task(chain, testChain_1); threadPool.push_task(chain, testChain_2); } ``` 5.获取线程数: ``` auto& threadPool{ hzw::ThreadPool::get_instance() }; size_t threadCount{ threadPool.thread_count() }; ``` **6.注意事项:** (1)线程池线程数默认为cpu核心数,释放线程池时默认等待任务全部完成 (2)设置线程池在第一次获取实例时有效,之后均无效 ``` hzw::ThreadPool::get_instance(true, 10);//设置有效 hzw::ThreadPool::get_instance(false, 5);//设置无效 ``` (3)如需保证某一任务完成执行,使用std::future同步 (4)执行链的本质:将相同执行链上的任务交由同一线程执行,可以提高线程池 **整体效能** , 但对同一执行链上的任务效能是否提升是不确定的,取决于同步块大小,同步块大建议使用执行链。 (5)使用回调接口时:`回调的参数与任务的返回值注意匹配`,`回调在任务结束后由同一线程立即执行`