QThread threadpool

QThread threadpool

本文关键字:threadpool QThread      更新时间:2023-10-16

我正在尝试使用 QThread 编写线程轮询。

class ThreadPool: public QObject
{
    Q_OBJECT
public:
    ThreadPool(int maxThreads);
    void addTask(MyTask *task);
private:
    int maxThreads;
    QMutex mutex;
    QVector<QPair<bool, QThread>> threads;
    QThread *getFreeThread();
public slots:
   void freeThread();
};

void ThreadPool::addTask(MyTask* task)
{
    QThread *thread = getFreeThread();
    task->moveToThread(thread);
    connect(thread, SIGNAL(started()), task, SLOT(doWork()));
    connect(task, SIGNAL(workFinished()), thread, SLOT(quit()));
    connect(thread, SIGNAL(finished()), task, SLOT(deleteLater()));
    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    connect(thread, SIGNAL(finished()), this, SLOT(freeThread()));
    thread->start();
}

我正在创建有限数量的线程,我想在其中执行任务。但是,我不明白如何获取释放线程的编号。我知道QThreadPool和Qtconcurrent,但我不想使用它。也许,值得注意的是 QPair 向量中的每个线程是否免费。

  1. 您实际上并不需要QVector<QPair<bool, QThread>>来跟踪池中的所有线程,而是使用仅包含指向空闲线程的指针的QList< QThread* >

    private:
         QList<QThread*> freeThreads; // only free threads
         QList<QThread*> allThreads; // just to count the number of all threads
    
  2. 在插槽 freeThread(( 中使用 QObject 中的 sender(( 方法来获取信号发送者的指针,在本例中将是 QThread,它已经变得自由

    void ThreadPool::freeThread()
    {
         // get the pointer to the thread that sent the signal:
         QObject* threadFreed = QObject::sender();
         if( ! freeThreads.contains( threadFreed ) )
         {
              // save the thread pointer in list
              freeThreads << threadFreed;
         }
    }
    
  3. 最后getFreeThread((可以看起来像这样:

    QThread* getFreeThread()
    {
         if( ! freeThreads.isEmpty() )
         {
              // take the first free thread
              return freeThreads.takeFirst();
         }
         else
         {
              if(allThreads.size() < maxThreads )
              {
                 // create a new thread 
                 QThread* thread = new QThread(this);
                 allThreads << thread;
                 return thread;
              }
              else
              {
                // Maximum number of threads exceeded 
                // and no free thread is available
                 return NULL;
              }
         }
    }
    

此外,您还应该处理在addTask中返回NULL 指针的情况:

void ThreadPool::addTask(MyTask* task)
{
    QThread *thread = getFreeThread();
    if( ! thread )
    {
        // do something else
        return;
    }
    // proceed with thread execution ...
}