在C++中,线程池是一种用于管理和复用线程的机制,以减少线程创建和销毁的开销,并提高系统的响应速度和吞吐量。下面是一个简单的C++线程池实现的概述:
线程池设计
线程池大小:确定线程池中线程的数量。
任务队列:用于存储待执行的任务。
线程管理:创建、启动、管理和销毁线程。
任务调度:从任务队列中取出任务并分配给空闲线程执行。
示例如下:
- #pragma once
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
-
-
- class ThreadPool
- {
- public:
- ThreadPool(size_t count);
- ~ThreadPool();
- ThreadPool(const ThreadPool&) = delete; //禁用拷贝构造
- const ThreadPool& operator=(const ThreadPool&) = delete; //禁用赋值运算符
- void threadLoop();
- void addTask(std::function<void()> &task);
-
- private:
- std::vector
_threads; - std::queue
void()>> _tasks; - std::mutex _mtx;
- std::condition_variable _cv;
- bool _stop;
- };
- #include "ThreadPool.h"
-
- ThreadPool::ThreadPool(size_t count): _stop(false)
- {
- _threads.reserve(count);
- for (size_t i = 0; i < count; ++i)
- {
- _threads.emplace_back(
- new std::thread(std::bind(&ThreadPool::threadLoop, this))
- );
- }
- }
-
- ThreadPool::~ThreadPool()
- {
- std::unique_lock
lock(_mtx) ; - _stop = true;
- _cv.notify_all();
- for (auto it = _threads.begin(); it != _threads.end(); ++it)
- {
- (*it)->join();
- delete *it;
- }
- _threads.clear();
- }
-
- void ThreadPool::threadLoop()
- {
- while (!_stop)
- {
- std::unique_lock
lock(_mtx) ; - if(_tasks.empty())
- _cv.wait(lock);
- if (!_tasks.empty())
- {
- std::function<void()> task = _tasks.front();
- _tasks.pop();
- task(); //执行任务
- }
- }
- }
-
- void ThreadPool::addTask(std::function<void()> &task)
- {
- std::unique_lock
lock(_mtx) ; - _tasks.emplace(task);
- _cv.notify_one();
- }
Qt线程池:
Qt 提供了一个线程池(QThreadPool)来简化多线程编程。只需将任务(通常是以 QRunnable 或其子类形式的任务)提交给线程池,然后由线程池自动处理任务的分配和执行。
以下是使用 Qt 线程池的基本步骤:
1、包含必要的头文件
- #include
- #include
2、创建自定义任务
创建一个继承自 QRunnable 的类,并实现 run() 方法。这个方法将包含你的任务代码。
- class MyTask : public QRunnable
- {
- public:
- void run() override {
- // 在这里编写你的任务代码
- }
- };
3、提交任务到线程池
使用 QThreadPool::globalInstance() 获取全局线程池的实例,然后调用 start() 方法来提交任务。
- MyTask *task = new MyTask();
- QThreadPool::globalInstance()->start(task);
- // 注意:task 对象将在任务完成后自动删除,除非你设置了不同的删除策略
4、配置线程池
你可以使用 QThreadPool 的各种方法来配置线程池的行为,例如设置最大线程数:
QThreadPool::globalInstance()->setMaxThreadCount(4); // 设置最大线程数为 4
5、处理任务结果
如果你的任务需要返回结果,你可以使用信号和槽机制来在任务完成时发送结果。在你的 QRunnable 子类中,当任务完成时发出一个信号,然后在需要的地方连接这个信号到一个槽。
6、线程安全
在多线程环境中编程时,确保你的代码是线程安全的。避免在多个线程中同时访问和修改共享数据,除非你已经采取了适当的同步措施(如互斥锁)。
7、清理和关闭
当应用程序关闭时,Qt 将自动清理和关闭线程池。然而,如果你需要手动关闭线程池或等待所有任务完成,你可以使用 QThreadPool 的相关方法。
注意:Qt 线程池非常适合处理简单的并行任务,但对于复杂的并发需求(如需要精确控制线程生命周期或同步的情况),你可能需要直接使用 QThread 或其他更底层的并发机制。