2017-03-31 23 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. あなたは本当に代わりに、空きスレッドへのポインタのみを保持しているQList< QThread* >を使用し、あなたのプール内のすべてのスレッドを追跡するためにQVector<QPair<bool, QThread>>は必要ありません。

    スロットfreeThreadで
    private: 
        QList<QThread*> freeThreads; // only free threads 
        QList<QThread*> allThreads; // just to count the number of all threads 
    
  2. ()フリーとなっているQThread、あろう。この場合の信号送信側のポインタを取得するためにはQObjectから送信者()メソッドを使用

    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を処理する必要がありますaddTaskにNULLポインタが返されたときにaseを返します。

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