Reputation: 456
I am trying to write thread poll with 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();
}
I am creating a limited number of threads in which I want to perform tasks. However, I do not understand how to get the number of the freed thread. I know about QThreadPool and Qtconcurrent, but I dont want to use it. Perhaps, it is worth noting at each thread in QPair's vector is it free or not.
Upvotes: 0
Views: 1579
Reputation: 2000
you do not really need a QVector<QPair<bool, QThread>>
to keep track of all the threads in your Pool, instead use a QList< QThread* >
which holds only the pointers to the free threads.
private:
QList<QThread*> freeThreads; // only free threads
QList<QThread*> allThreads; // just to count the number of all threads
In the slot freeThread() use the sender() method from QObject to get the pointer of the signal sender, which in this case will be the QThread, that has become free
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;
}
}
Finally getFreeThread() can look like this:
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;
}
}
}
Also you should handle the case when a NULL pointer is returned in addTask:
void ThreadPool::addTask(MyTask* task)
{
QThread *thread = getFreeThread();
if( ! thread )
{
// do something else
return;
}
// proceed with thread execution ...
}
Upvotes: 2