@@ -113,7 +113,6 @@ int main() {
113113
114114> [运行](https://godbolt.org/z/h5G5hTT4a)测试。
115115
116-
117116- 创建线程池时,指定线程数量,线程池会创建对应数量的线程。
118117
119118- 使用 `boost::asio::post` 提交任务,任务会被添加到任务队列中。
@@ -168,6 +167,73 @@ boost::asio::post(pool, task); // 将任务加入线程池
168167pool.join(); // 等待任务完成 (或者析构自动调用)
169168```
170169
170+ ### `QThreadPool`
171+
172+ [`QThreadPool`](https://doc.qt.io/qt-6/qthreadpool.html) 是 Qt 提供的线程池实现,它是用来管理自家的 `QThreads` 的集合。
173+
174+ ```cpp
175+ #include <QCoreApplication>
176+ #include <QThreadPool>
177+ #include <QRunnable>
178+ #include <QDebug>
179+
180+ struct MyTask : public QRunnable{
181+ void run() override {
182+ qDebug() << "🐢🐢🐢🐢🐢";
183+ }
184+ };
185+
186+ int main(int argc, char *argv[]){
187+ QCoreApplication app(argc, argv);
188+
189+ QThreadPool *threadPool = QThreadPool::globalInstance();
190+
191+ // 线程池最大线程数
192+ qDebug()<< threadPool->maxThreadCount();
193+
194+ for (int i = 0; i < 10; ++i) {
195+ MyTask *task = new MyTask{};
196+ threadPool->start(task);
197+ }
198+ // 当前活跃线程数 10
199+ qDebug()<<threadPool->activeThreadCount();
200+
201+ app.exec();
202+ }
203+ ```
204+
205+ 与 ` Asio.thread_pool ` 不同,` QThreadPool ` 采用单例模式,通过静态成员函数 ` QThreadPool::globalInstance() ` 获取对象实例。默认情况下,` QThreadPool ` 线程池的最大线程数为当前硬件支持的并发线程数,例如在我的硬件上为 ` 20 ` ,这点也和 ` Asio.thread_pool ` 不同。
206+
207+ ` QThreadPool ` 依赖于 Qt 的事件循环,因此我们使用了 ` QCoreApplication ` 。
208+
209+ 而将任务添加到线程池中的做法非常古老原始,我们需要** 自定义一个类型继承并重写虚函数 ` run ` ** ,创建任务对象,然后将任务对象传递给线程池的 ` start ` 方法。
210+
211+ 在 Qt6,引入了一个 [ ` start ` ] ( https://doc.qt.io/qt-6/qthreadpool.html#start-1 ) 的重载版本:
212+
213+ ``` cpp
214+ template <typename Callable, QRunnable::if_callable<Callable>>
215+ void QThreadPool::start (Callable &&functionToRun, int priority)
216+ {
217+ start(QRunnable::create(std::forward<Callable >(functionToRun)), priority);
218+ }
219+ ```
220+
221+ 它相当于是对[`start` 原始版本](https://doc.qt.io/qt-5/qthreadpool.html#start)的:
222+
223+ ```cpp
224+ void start(QRunnable *runnable, int priority = 0);
225+ ```
226+
227+ > [ 源码] ( https://codebrowser.dev/qt6/qtbase/src/corelib/thread/qthreadpool.cpp.html#_ZN11QThreadPool5startEP9QRunnablei ) 。
228+
229+ 进行的一个** 包装** ,以支持任何的[ * 可调用(* Callable* )* ] ( https://zh.cppreference.com/w/cpp/named_req/Callable ) 类型,而无需再繁琐的继承重写 ` run ` 函数。
230+
231+ ``` cpp
232+ threadPool->start ([ =] {
233+ qDebug()<<QString("thread id %1").arg(i);
234+ });
235+ ```
236+
171237## 实现线程池
172238
173239实现一个普通的能够满足日常开发需求的线程池实际上非常简单,也只需要一百多行代码。
0 commit comments