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.

 

 

你可能感兴趣的:(NetWork)