QNetworkAccessManager的异步与线程
Qt版本5.1.1
以HTTP操作为例
Qt中的HTTP操作都是异步的. 内部通过线程实现
创建线程的时机在QNetworkReplyHttpImplPrivate::postRequest()
void QNetworkReplyHttpImplPrivate::postRequest()
{
Q_Q(QNetworkReplyHttpImpl);
QThread *thread = 0;
if (synchronous) {
// A synchronous HTTP request uses its own thread
thread = new QThread();
thread->setObjectName(QStringLiteral("Qt HTTP synchronous thread"));
QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
} else if (!managerPrivate->httpThread) {
// We use the manager-global thread.
// At some point we could switch to having multiple threads if it makes sense.
managerPrivate->httpThread = new QThread();
managerPrivate->httpThread->setObjectName(QStringLiteral("Qt HTTP thread"));
managerPrivate->httpThread->start();
thread = managerPrivate->httpThread;
} else {
// Asynchronous request, thread already exists
thread = managerPrivate->httpThread;
}
..........
// Move the delegate to the http thread
delegate->moveToThread(thread);
// This call automatically moves the uploadDevice too for the asynchronous case.
...........
}
分为两种情况:
(1) synchronous == true 每次HTTP请求创建自己的线程, 并在finished后自动退出线程
在QNetworkRequest设置QNetworkRequest::SynchronousRequestAttribute 属性为真时, synchronous = true, 然而SynchronousRequestAttribute被Qt标记为internal. 以防止外部创建synchronous HTTP请求.
我在Qt的源码中找到一点说明, QNetworkReplyHttpImpl的构造函数中.
........
// Internal code that does a HTTP reply for the synchronous Ajax
// in Qt WebKit.
QVariant synchronousHttpAttribute = request.attribute(
static_cast<QNetworkRequest::Attribute>(QNetworkRequest::SynchronousRequestAttribute));
if (synchronousHttpAttribute.isValid()) {
d->synchronous = synchronousHttpAttribute.toBool();
........
webkit的ajax请求使用
(2) synchronous == false 则把所有http请求放置在一个线程中.
并且该线程在
QNetworkAccessManagerPrivate对象析构(即QNetworkAccessManager析构)或者调用QNetworkAccessManagerPrivate::clearCache 时退出
QNetworkAccessManagerPrivate::~QNetworkAccessManagerPrivate()
{
if (httpThread) {
httpThread->quit();
httpThread->wait(5000);
if (httpThread->isFinished())
delete httpThread;
else
QObject::connect(httpThread, SIGNAL(finished()), httpThread, SLOT(deleteLater()));
httpThread = 0;
}
}
void QNetworkAccessManagerPrivate::clearCache(QNetworkAccessManager *manager)
{
manager->d_func()->objectCache.clear();
manager->d_func()->authenticationManager->clearCache();
if (manager->d_func()->httpThread) {
manager->d_func()->httpThread->quit();
manager->d_func()->httpThread->wait(5000);
if (manager->d_func()->httpThread->isFinished())
delete manager->d_func()->httpThread;
else
QObject::connect(manager->d_func()->httpThread, SIGNAL(finished()), manager->d_func()->httpThread, SLOT(deleteLater()));
manager->d_func()->httpThread = 0;
}
}
否则会一直HTTP 线程会一直存在. 另外, 每个QNetworkAccessManager对象对应自己的HTTP thread.


浙公网安备 33010602011771号