2017-03-31 123 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 ... 
}