# ThreadPool C++11
## 多线程程序一定好吗?
不一定,要看当前程序的类型来判断,程序的类型有IO密集型和CPU密集型。
- IO密集型:涉及一些IO操作的指令,比如设备、文件、网络等,这些IO操作很容易阻塞程序,也是比较耗时的操作。
- CPU密集型:指令主要是用于计算的。
对于多核计算机来说,这两种类型的程序使用多线程都是有必要的,但是如果是**单线程环境,IO密集型程序才适合多线程**,比如某个任务处于网络阻塞状态,那就可以切换其他线程去处理其他任务;CPU密集型程序不适合多线程,因为就算是多个线程,这些计算指令依然还是这个核心来处理,除了执行指令外,还多了一些线程切换开销。
## 线程数量怎么确定?
- 线程的创建核销毁是非常"重"的操作。
- 线程本身占用大量内存。每个线程都有自己独立的栈空间。
- 线程的上下文切换非常耗时。如果cpu大量时间花在切换线程,就没时间处理任务了。
- 大量线程同时唤醒会使得系统出现瞬时负载量过大导致宕机。
**线程数量一般都是按照当前CPU的核心数量来确定的。**
## 线程池介绍
### 线程池基本原理
为了任务得到及时的处理(所谓任务可以理解为待执行的函数),把待处理的任务都放入线程池的任务队列中,线程池的多个线程就可以从该任务队列中取出任务并执行,线程再取出任务的同时,用户也可以向任务队列中添加新的任务,就好像用户只管把要执行的任务告诉线程池,线程池内部线程处理完成后返回用户处理结果。大致原理如下图。
![image.png](https://cdn.nlark.com/yuque/0/2023/png/27222704/1674735325442-b2fadb6c-4091-4c17-b12f-78eb4c181c87.png#averageHue=%23998476&clientId=u0ee95a07-4455-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=557&id=u49939487&margin=%5Bobject%20Object%5D&name=image.png&originHeight=696&originWidth=1108&originalType=binary&ratio=1&rotation=0&showTitle=false&size=50875&status=done&style=none&taskId=uf7503347-6b66-40a1-b82e-757490cb966&title=&width=886.4)
有读者可能疑问,函数不是调用了就执行了吗,怎么还可以放入什么任务队列?是的,C++11提供了function模板,可以把函数当作一个可调用对象(可理解为一个变量)先保存起来,甚至可以把这个可调用对象存入容器中(比如queue中),然后可以再合适的时机把该调用对象取出来,然后执行。相当于把要执行的函数保存后延迟调用。
### 线程池的优势
- 服务进程启动之初,就事先在线程池重创建好了很多线程,当有任务需要执行时,就可以直接选择一个线程马上执行任务,而不必像之前一样,执行任务还需要额外时间先创建好线程。
- 任务执行完成后,不用释放线程,而是把线程归还到线程池中,便于为后续任务提供服务。
### 线程池应该具备的功能
- 线程池应该是可配置的。比如配置保留线程的数量,线程池最多能开启的线程数量等。
- 具有保留线程和动态线程。保留线程常驻在线程池中,只要线程池没有退出或者被回收,则常驻线程就不会终止;动态线程根据任务量的大小动态创建和销毁,当保留线程不能及时处理任务队列的任务时,增加动态线程,当任务队列为空,许多动态线程处于等待状态时,终止动态线程。
- 能够执行各种不一样的任务(参数不同的函数),并且能够获取执行结果
- 可获取当前线程池中线程的总个数,空闲线程的个数。
- 可以控制任务队列的任务数量,防止过多任务占用大量内存。
- 开启线程池功能的开关。关闭时确保当前任务能够执行完成,并丢弃剩下没有执行的任务,或者停止向任务队列中添加新任务,把剩余的任务执行完毕后退出。
## 线程池的实现
### 前置知识
本线程池使用C++11编写,主要使用到了以下的C++11特性,适合初学者入门。
std::function和std::bind、可变参数函数模板、package_task和future、原子类型(atomic)、条件变量、互斥锁、智能指针、lambda表达式、移动语义、完美转发
### 类的划分
线程池中共分为两个类,一个Thread类和一个ThreadPool类,Thread类主要是用于保存线程的一些基本属性、比如线程标志(是保留线程还是动态线程)、线程ID、std::thread等等,涉及到的方法主要是启动线程(start函数);ThreadPool类主要用于管理Thread类和任务队列,包括动态添/删除线程、向任务队列存取任务等等。这两个类的头文件主要代码如下:
```cpp
class Thread : public std::enable_shared_from_this<Thread>
{
public:
using ThreadPtr = std::shared_ptr<Thread>;
using ThreadFunc = std::function<void(ThreadPtr)>;
enum class ThreadFlag { kReserved, kDynamic };
explicit Thread(ThreadFunc func, ThreadFlag flag = ThreadFlag::kReserved);
~Thread() = default;
// 获取线程id
pid_t getThreadId() { return threadId_; }
void start(); // 启动线程
private:
ThreadFlag threadFlag_; // 线程标志
pid_t threadId_; // 线程id
std::thread thread_; // 线程
ThreadFunc threadFunc_; // 线程执行函数
};
```
```cpp
class ThreadPool
{
public:
using Task = std::function<void()>; // 定义任务回调函数
using Seconds = std::chrono::seconds;
using ThreadPoolLock = std::unique_lock<std::mutex>;
using ThreadPtr = std::shared_ptr<Thread>; // 线程指针类型
using ThreadFlag = Thread::ThreadFlag;
explicit ThreadPool();
~ThreadPool();
void start(); // 开启线程池
void stop(); // 停止线程池
template<typename Func, typename... Args> // 给线程池提交任务
auto submitTask(Func&& func, Args&&... args) -> std::future<decltype(func(args...))>;
private:
void addThread(ThreadFlag flag = ThreadFlag::kReserved);// 向线程池中添加一个新线程
void removeThread(pid_t id);
void threadFunc(ThreadPtr threadPtr); // 线程执行函数
std::list<ThreadPtr> workThreads_; // 存放工作线程,使用智能指针是为了能够自动释放Thread
std::mutex threadMutex_; // 工作线程互斥锁
std::queue<Task> tasks_; // 任务队列
std::mutex taskMutex_; // 互斥锁(从队列取出/添加任务用到)
std::condition_variable notFullCV_; // 任务队列不满
std::condition_variable notEmptyCV_; // 任务队列不空
std::condition_variable exitCV_; // 没有任务时方可线程池退出
// std::atomic_int taskNum_; // 任务队列中未处理的任务数量
std::atomic_int waitingThreadNum_; // 处于等待中的线程数量
std::atomic_uint curThreadNum_; // 当前线程数量
std::atomic_bool quit_; // 标识是否退出线程池
Config config_; // 存储线程池配置
};
```
### 功能实现
#### ThreadPool构造函数做了什么?
构造函数主要初始化一些配置,比如保留线程的数量、线程池最大的线程数量等等。
#### 线程池启动(start)时做了什么?
线程池调用start函数后,会根据配置中给定的保留线程数量向线程容器`workThreads_`中添加保留线程,添加保留线程实际上就是创�
没有合适的资源?快使用搜索试试~ 我知道了~
C++实现线程池详解(基于boost源码以及封装等线程池)
共128个文件
hpp:26个
cmake:16个
txt:11个
5 下载量 11 浏览量
2023-10-15
23:24:47
上传
评论 1
收藏 888KB ZIP 举报
温馨提示
一、要实现高效的线程池,可以考虑以下几点 二、实现线程池可以按照以下步骤进行 三、简单的C++线程池代码示例 四、 基于boost编写的源码库 - 线程池 4.1 基于boost编写的源码库地址 4.2 boost线程池的先进先出、后进先出、优先级代码示例 五、看看人家线程池怎么写的 - 要理解精髓 六、线程池应用场景与实践 6.1 服务器应用 6.2 数据处理与计算密集型任务 6.3 图形界面与事件驱动程序 七、C++线程池高级应用与实际案例 7.1 基于负载均衡的任务分配策略 7.2 线程池性能优化技巧 八、实际案例分析与优秀实践 8.1 案例一:并发网络服务 8.2 案例二:并行计算与数据处理 8.3 案例三:高性能Web服务器
资源推荐
资源详情
资源评论
收起资源包目录
C++实现线程池详解(基于boost源码以及封装等线程池) (128个子文件)
CMakeDetermineCompilerABI_C.bin 16KB
CMakeDetermineCompilerABI_CXX.bin 16KB
CMakeDetermineCompilerABI_CXX.bin 8KB
CMakeDetermineCompilerABI_C.bin 8KB
CMakeCCompilerId.c 24KB
CMakeCCompilerId.c 20KB
testBoostGroup.cbp 9KB
ThreadPool.cc 5KB
main.cc 1KB
Thread.cc 566B
cmake.check_cache 85B
cmake.check_cache 85B
CMakeCXXCompiler.cmake 6KB
CMakeCXXCompiler.cmake 5KB
Makefile.cmake 5KB
CMakeCCompiler.cmake 3KB
CMakeCCompiler.cmake 2KB
Makefile.cmake 2KB
cmake_install.cmake 2KB
cmake_install.cmake 1KB
DependInfo.cmake 811B
DependInfo.cmake 780B
CMakeDirectoryInformation.cmake 730B
CMakeDirectoryInformation.cmake 686B
CMakeSystem.cmake 398B
CMakeSystem.cmake 362B
cmake_clean.cmake 361B
cmake_clean.cmake 270B
CMakeCXXCompilerId.cpp 24KB
CMakeCXXCompilerId.cpp 20KB
main.cpp 2KB
main.cpp 1KB
thread_test.cpp 987B
main.cpp.o.d 73KB
thread_test.cpp.o.d 72KB
.DS_Store 6KB
.DS_Store 6KB
.DS_Store 6KB
.DS_Store 6KB
.DS_Store 6KB
.gitignore 176B
ThreadPool.h 4KB
Thread.h 947B
Config.h 518B
thread_test.h 267B
pool_core.hpp 14KB
pool_core.hpp 14KB
pool.hpp 7KB
pool.hpp 7KB
scheduling_policies.hpp 6KB
scheduling_policies.hpp 6KB
future.hpp 4KB
future.hpp 4KB
task_adaptors.hpp 4KB
task_adaptors.hpp 4KB
worker_thread.hpp 3KB
worker_thread.hpp 3KB
future.hpp 3KB
future.hpp 3KB
size_policies.hpp 2KB
size_policies.hpp 2KB
locking_ptr.hpp 2KB
locking_ptr.hpp 2KB
pool_adaptors.hpp 2KB
pool_adaptors.hpp 2KB
shutdown_policies.hpp 2KB
shutdown_policies.hpp 2KB
scope_guard.hpp 1006B
scope_guard.hpp 1006B
threadpool.hpp 663B
threadpool.hpp 663B
testBoostGroup.iml 97B
CXX.includecache 153KB
compiler_depend.internal 140KB
depend.internal 43KB
cache-v2-aa45b7b3ce04f56c7700.json 21KB
target-test-2890c3fa1b125f10e03f.json 4KB
toolchains-v1-ec6e94d0d30e763f979b.json 2KB
index-2023-10-11T14-42-00-0097.json 2KB
codemodel-v2-3c56064a1ee76ff94e13.json 1KB
c_cpp_properties.json 373B
directory-.-f5ebdc15457944623624.json 154B
query.json 110B
settings.json 100B
CMakeOutput.log 44KB
CMakeOutput.log 40KB
CMakeError.log 692B
compiler_depend.make 215KB
depend.make 75KB
build.make 6KB
build.make 5KB
flags.make 500B
flags.make 354B
depend.make 88B
progress.make 64B
progress.make 43B
Makefile 6KB
Makefile 6KB
Makefile 5KB
Makefile2 4KB
共 128 条
- 1
- 2
资源评论
Allen.Su
- 粉丝: 422
- 资源: 3
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功