天天看点

Qt线程池QThreadPool源码学习笔记

  1. QList<QThreadPoolThread *> allThreads; //所有线程
  2. QQueue<QThreadPoolThread *> waitingThreads; // 等待队列,当一个线程中完成它的工作后,如果发现现有正在工作的线程数没有超过设定上限数量,放到这里,线程等待一定的时间,如果超时了,将这个线程放到expiredThreads
  3. QQueue<QThreadPoolThread *> expiredThreads; //到期队列,当一个线程中完成它的工作后,如果发现现有正在工作的线程数超过设定上限数量,将线程停止,放到这里
  4. QVector<QueuePage*> queue; //任务列表,存QueuePage的队列,所有需要在线程中进行的工作(QRunnable 类)都记录在这里。列表中的任务按优先级排序。
  5. QueuePage //相同优先级QRunnable的队列
  6. QRunnable //线程中进行实际工作的类,用户需要从QRunnable继承,实现具体的任务处理(如果设置了autoDelete,它将会在线程处理完它之后delete,不用手动delete)

QThreadPool::start(QRunnable *runnable, int priority); //线程池添加QRunnable的逻辑是:

  1. 池中线程数量为0:创建线程,添加到allThreads中,并开始工作
  2. 池中线程数量不为0:

    2.1 当前工作中的线程数超出了允许的最大值,将任务QRunnable加入任务队列,如果等待队列不为空,尝试唤醒队列头部的线程

    2.2 当前工作中的线程数没有超出允许的最大值。如果有等待线程,则将任务QRunnable加入任务队列,并唤醒队列头部的线程。如果没有等待线程,则从到期线程中取出一个,将这项任务交给他,并开始工作。

线程池处理工作的优先级功能:

在加入工作QRunnable时有一个可选参数priority,它的值默认为0。

start(QRunnable *runnable, int priority);

这项任务会添加到任务列表中

QVector<QueuePage*> queue;

,添加时根据优先级值进行排序,数值小的在前,优先处理。

for (QueuePage *page : qAsConst(queue)) {
        if (page->priority() == priority && !page->isFull()) {
            page->push(runnable);
            return;
        }
    }
    auto it = std::upper_bound(queue.constBegin(), queue.constEnd(), priority, comparePriority);
    queue.insert(std::distance(queue.constBegin(), it), new QueuePage(runnable, priority));