The Structure of QThreadPoolPrivate

 

The Structure of QThreadPoolPrivate

       Yesterday, we make an assay of QThreadPoolPrivate. But when we came to know the mechanism of enqueueTask () function, it has no way to know the underlying implementation. So we come to the QThreadPoolPrivate class today.

       Now, let’s look at the QThreadPoolThread and the QThreadPoolPrivate class.

       The QThreadPoolThread class is inherited from QThread.

/*

    QThread wrapper, provides synchronizitaion against a ThreadPool

*/

class QThreadPoolThread : public QThread

{

public:

    QThreadPoolThread(QThreadPoolPrivate *manager);

    void run();

    void registerTheadInactive();

 

    QThreadPoolPrivate *manager;

    QRunnable *runnable;

};

       From the definition of this class, we can guess when the QThreadPool class was living, it create some object of QThreadPoolThread. Then hang the thread and wait for the QThreadPoolThread::start () function is called.

       The thread object was hanged by the follow codes.

       void QThreadPoolThread::run()

{

    QMutexLocker locker(&manager->mutex);

    for(;;) {

        QRunnable *r = runnable;

        runnable = 0;

 

        do {

            if (r) {

                const bool autoDelete = r->autoDelete();

 

 

                // run the task

                locker.unlock();

#ifndef QT_NO_EXCEPTIONS

                try {

#endif

                    r->run();

#ifndef QT_NO_EXCEPTIONS

                } catch (...) {

                    qWarning("Qt Concurrent has caught an exception thrown from a worker thread./n"

                             "This is not supported, exceptions thrown in worker threads must be/n"

                             "caught before control returns to Qt Concurrent.");

                    registerTheadInactive();

                    throw;

                }

#endif

                locker.relock();

 

                if (autoDelete && !--r->ref)

                    delete r;

            }

 

            // if too many threads are active, expire this thread

            if (manager->tooManyThreadsActive())

                break;

 

            r = !manager->queue.isEmpty() ? manager->queue.takeFirst().first : 0;

        } while (r != 0);

 

        if (manager->isExiting) {

            registerTheadInactive();

            break;

        }

 

        // if too many threads are active, expire this thread

        bool expired = manager->tooManyThreadsActive();

        if (!expired) {

            ++manager->waitingThreads;

            registerTheadInactive();

            // wait for work, exiting after the expiry timeout is reached

            expired = !manager->runnableReady.wait(locker.mutex(), manager->expiryTimeout);

            ++manager->activeThreads;

   

            if (expired)

                --manager->waitingThreads;

        }

        if (expired) {

            manager->expiredThreads.enqueue(this);

            registerTheadInactive();

            break;

        }

    }

}

 

       In order to support multi-thread synchronization, they create a QMutexLocker object by the following code.

QMutexLocker locker(&manager->mutex);

And then call an endless loop(for(;;)), after this, they create a point of QRunnable class.

QRunnable *r = runnable;

runnable = 0;

Here we can guess, this point points to the class, we create it by ourselves, which is inherited from QRunnable class. It is similar to the callback function.

Then they unlock the mutex, and run the task.

locker.unlock();

#ifndef QT_NO_EXCEPTIONS

                try {

#endif

                    r->run();

#ifndef QT_NO_EXCEPTIONS

                } catch (...) {

                    qWarning("Qt Concurrent has caught an exception thrown from a worker thread./n"

                             "This is not supported, exceptions thrown in worker threads must be/n"

                             "caught before control returns to Qt Concurrent.");

                    registerTheadInactive();

                    throw;

                }

After the run () function returns. They do some cleaning work, and wait for the next task comes.

It’s time to go to sleep. That’s all for this class. The next day, I will do some analyze about the network framework.

 

November 13, 2009 23:41

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值