2017-03-31 122 views
0

我想用QThread編寫線程輪詢。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的矢量中的每個線程都是免費的。

+0

只是爲了完整起見,存在一個可以使用的QThreadPool類。 –

回答

1
  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的發送者()方法來獲得的信號發送器,在這種情況下將是的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; 
          } 
        } 
    
    } 
    

你也應該處理的C ase當在addTask中返回NULL指針時:

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