【发布时间】:2016-12-21 21:45:21
【问题描述】:
谁能提供使用 QThreadPool 类中的“reserveThread”和/或“releaseThread”的示例?我已经阅读了文档,但我真的不明白你什么时候会使用这些功能。互联网搜索的例子都是空的。
我使用的是 PySide,所以首选 Python,但 C++ 也不错。
【问题讨论】:
谁能提供使用 QThreadPool 类中的“reserveThread”和/或“releaseThread”的示例?我已经阅读了文档,但我真的不明白你什么时候会使用这些功能。互联网搜索的例子都是空的。
我使用的是 PySide,所以首选 Python,但 C++ 也不错。
【问题讨论】:
这些方法用于将线程池与您手动管理的线程进行互操作。
线程池保留活动线程的计数,并旨在使其不超过在给定硬件上有意义的最大线程数。 reserveThread 和releaseThread 更改池知道的活动线程数。它不会直接从池中添加或删除任何线程。 这些方法不返回 QThread 并不是错误。
reserveThread 表示:“我正在使用我在其他地方管理的线程,因此请考虑我的线程处于活动状态,即使它不是你的(线程池的)。
releaseThread 表示:“我不再使用我的线程了,请随意激活更多线程。”
示例:考虑一个四逻辑 CPU 系统。代码是 C++。
最初:
QThreadPool pool;
assert(pool.maxThreadCount() == 4);
assert(pool.activeThreadCount() == 0);
您启动了一个专门的计算线程:一个核心变得忙碌。您可以致电reserveThread 通知矿池:
MyWorker worker;
QThread thread;
worker.moveToThread(&thread);
thread.start();
pool.reserveThread();
assert(pool.activeThreadCount() == 1);
池本身没有运行任何线程!
您提交了四个可运行文件,每个都需要一段时间。池创建三个额外的线程来执行它们:
QAtomicInt act = 0;
QtConcurrent.run(&pool, [&]{ act.ref(); QThread::sleep(60); act.deref(); });
QtConcurrent.run(&pool, [&]{ act.ref(); QThread::sleep(60); act.deref(); });
QtConcurrent.run(&pool, [&]{ act.ref(); QThread::sleep(60); act.deref(); });
QtConcurrent.run(&pool, [&]{ act.ref(); QThread::sleep(60); act.deref(); });
QThread::sleep(1);
assert(pool.activeThreadCount() == 4);
assert(act.load() == 3);
现在只有三个可运行项处于活动状态,因为四分之一的线程被保留并且不能处于活动状态:它没有 CPU 可以运行,因为您的线程在那里很忙。
您的计算线程已完成,您可以释放一个内核。您可以致电releaseThread 通知矿池:
thread.quit();
thread.wait();
pool.releaseThread();
QThread::sleep(1);
assert(pool.activeThreadCount() == 4);
assert(act.load() == 4);
由于存在额外的可运行等待,因此激活了一个线程以使可运行继续运行。
一分钟后,所有的runnables都完成了,没有更多的活动线程:
QThread::sleep(60);
assert(pool.activeThreadCount() == 0);
assert(act.load() == 0);
【讨论】:
reserveThread,那么 activeThreadCount 将暂时增加到 5,即使这高于最大线程数。当其中一个正在运行的线程完成时,activeThreadCount 将返回到 4。感谢您的解释。