-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy paththreadpool.h
More file actions
98 lines (75 loc) · 3.24 KB
/
threadpool.h
File metadata and controls
98 lines (75 loc) · 3.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#ifndef __THREAD_POOL__
#define __THREAD_POOL__
#include <vector>
#include <queue>
#include <memory>
#include <atomic>
#include <mutex>
#include <functional>
#include <thread>
#include <condition_variable>
const int DEFAULT_THREAD_NUM = 4;
// 线程池的模式
enum class PoolMode {
FIXED_MODE, // 固定数量的线程
CACHED_MODE // 线程数量可以动态增长
};
// 任务(抽象基类),用户可以自定义任何任务类型,继承 Task 类,
// 然后重写 run 方法
class Task {
public:
virtual void run() = 0;
private:
};
// 线程类的封装,提供更加友好的线程管理接口
class Thread {
public:
// 可以绑定任何可调用对象,使用绑定器绑定了 this 指针
using ThreadFunc = std::function<void()>;
Thread(ThreadFunc func);
~Thread();
// 启动单个线程,并设置线程为 detach 模式
void start();
private:
// 线程要执行的函数
ThreadFunc m_func;
};
// fixed 模式不需要考虑线程安全,因为线程池对象初始化直接创建好了线程
// cached 模式需要考虑线程安全,线程回收可能要在不同的线程对线程队列删除
// 对于任务队列,需要使用多态,所以使用指针,为了保证任务队列的生命周期
// (考虑用户提交任务是否传进来一个临时对象),需要使用智能指针
// 使用智能指针管理线程列表
// 记录任务个数的成员变量需要考虑线程安全问题,使用原子类型就行了 => 为什么需要单独一个变量记录任务数量?
// 线程池不需要拷贝构造和赋值 -> why:包含不可拷贝资源
// 在 ThreadPool 中添加 threadHandler(OOP) 和 Thread 中添加 start(不能访问任务队列中的锁),全局函数这三种方案的对比
// 创建线程时使用 std::bind 绑定参数, std::function
// 为什么需要原子类型的 m_taskNum 变量?
class ThreadPool {
public:
ThreadPool();
~ThreadPool();
ThreadPool(const ThreadPool &) = delete;
ThreadPool &operator=(const ThreadPool &) = delete;
// 启动线程池中的所有线程
void start(int initThreadSize = DEFAULT_THREAD_NUM);
// 设置线程池工作模式
void setPoolMode(PoolMode mode);
// 设置任务队列的上限阈值
void setTaskQueMaxThreshold(int threshold);
// 向线程池提交任务
void submitTask(std::shared_ptr<Task> sp);
private:
// 定义线程函数
void threadFunc();
private:
std::vector<std::unique_ptr<Thread>> m_threads; // 线程列表
size_t m_initThreadSize; // 初始的线程数量
std::queue<std::shared_ptr<Task>> m_taskQue; // 任务队列
std::atomic_uint m_taskNum; // 任务数量
int m_taskQueMaxThreshold; // 任务队列数量上限的阈值
std::mutex m_mtx_taskQue; // 任务队列的互斥锁,保证任务队列的线程安全
std::condition_variable m_notFull; // 表示任务队列不满,向生产者发出消息
std::condition_variable m_notEmpty; // 表示任务队列不空,
PoolMode m_poolMode; // 当前线程池的工作模式
};
#endif