QThreadPool
部分,我们找到以下内容:
void QThreadPool::releaseThread()
释放之前由调用
reserveThread()
保留的线程。注意:在没有先保留线程的情况下调用此函数会暂时增加
maxThreadCount()
。当一个线程因等待更多工作而进入睡眠状态时,这非常有用,因为它允许其他线程继续执行。确保在等待结束后调用reserveThread()
,以便线程池可以正确地维护activeThreadCount()
。另请参见:
reserveThread()
。
void QThreadPool::reserveThread()
保留一个线程,不考虑
activeThreadCount()
和maxThreadCount()
。完成线程操作后,请调用
releaseThread()
以使其可重用。注意:此函数将始终增加活动线程数。这意味着通过使用此函数,
activeThreadCount()
可能返回大于maxThreadCount()
的值。另请参见:
releaseThread()
。
我想使用releaseThread()
使嵌套的并发映射成为可能,但在下面的代码中,它在waitForFinished()
中挂起:
#include <QApplication>
#include <QMainWindow>
#include <QtConcurrentMap>
#include <QtConcurrentRun>
#include <QFuture>
#include <QThreadPool>
#include <QtTest/QTest>
#include <QFutureSynchronizer>
struct Task2 { // only calculation
typedef void result_type;
void operator()(int count) {
int k = 0;
for (int i = 0; i < count * 10; ++i) {
for (int j = 0; j < count * 10; ++j) {
k++;
}
}
assert(k >= 0);
}
};
struct Task1 { // will launch some other concurrent map
typedef void result_type;
void operator()(int count) {
QVector<int> vec;
for (int i = 0; i < 5; ++i) {
vec.push_back(i+count);
}
Task2 task;
QFuture<void> f = QtConcurrent::map(vec.begin(), vec.end(), task);
{
// with out releaseThread before wait, it will hang directly
QThreadPool::globalInstance()->releaseThread();
f.waitForFinished(); // BUG: may hang there
QThreadPool::globalInstance()->reserveThread();
}
}
};
int main() {
QThreadPool* gtpool = QThreadPool::globalInstance();
gtpool->setExpiryTimeout(50);
int count = 0;
for (;;) {
QVector<int> vec;
for (int i = 0; i < 40 ; i++) {
vec.push_back(i);
}
// launch a task with nested map
Task1 task; // Task1 will have nested concurrent map
QFuture<void> f = QtConcurrent::map(vec.begin(), vec.end(),task);
f.waitForFinished(); // BUG: may hang there
count++;
// waiting most of thread in thread pool expire
while (QThreadPool::globalInstance()->activeThreadCount() > 0) {
QTest::qSleep(50);
}
// launch a task only calculation
Task2 task2;
QFuture<void> f2 = QtConcurrent::map(vec.begin(), vec.end(), task2);
f2.waitForFinished(); // BUG: may hang there
qDebug() << count;
}
return 0;
}
这段代码不会永远运行下去,它会在循环(1~10000)之后挂起,所有线程都在等待条件变量。
我的问题是:
- 为什么会挂起?
- 我能修复它并保留嵌套的并发映射吗?
开发环境:
Linux版本2.6.32-696.18.7.el6.x86_64; Qt4.7.4; GCC 3.4.5
Windows 7; Qt4.7.4; mingw 4.4.0