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.
