#pragma once
#include <QList>
#include <QThread>
#include "Worker.h"
#include <QObject>
class ThreadPool: public QObject
{
Q_OBJECT
public:
ThreadPool(int size);
~ThreadPool();
static ThreadPool* getInstance();
void addTask(std::function<void()> task, int index = -1);
private:
int size;
QList<QThread*> threadPool;
int threadIndex;
};
#include "ThreadPool.h"
#include <QThread>
#include "Worker.h"
ThreadPool::ThreadPool(int size): threadIndex(0), size(size)
{
for (int i = 0; i < size; i++)
{
QThread* thread = new QThread;
thread->start();
threadPool << thread;
}
}
ThreadPool::~ThreadPool()
{
for (int i = 0; i < threadPool.size(); i++)
{
threadPool[i]->exit();
threadPool[i]->wait();
delete threadPool[i];
}
}
ThreadPool* ThreadPool::getInstance()
{
static ThreadPool m_instance(5);
return &m_instance;
}
void ThreadPool::addTask(std::function<void()> task, int index)
{
Worker* worker = new Worker;
QThread* thread = nullptr;
connect(worker, &Worker::workDone, worker, &Worker::deleteLater);
worker->addTask(task);
if (index == -1)
{
thread = threadPool[threadIndex];
threadIndex = (threadIndex + 1) % size;
}
else
{
thread = threadPool[index % size];
}
worker->moveToThread(thread);
QMetaObject::invokeMethod(worker, "startTask", Qt::QueuedConnection);
}
#pragma once
#include <QThread>
#include <functional>
#include <QMutex>
class Worker : public QObject
{
Q_OBJECT
public:
Worker(QObject* parent = nullptr);
~Worker();
void addTask(std::function<void()> task);
signals:
void workDone();
private slots :
void startTask();
private:
QList<std::function<void()>> taskList;
QMutex mutex;
};
#include "Worker.h"
#include <QThread>
#include <QObject>
#include <QMutexLocker>
#include <QDebug>
Worker::Worker(QObject* parent)
: QObject(parent)
{
}
Worker::~Worker()
{
}
void Worker::addTask(std::function<void()> task)
{
QMutexLocker lock(&mutex);
taskList << task;
}
void Worker::startTask()
{
qDebug() << "start Worker" << thread();
QMutexLocker lock(&mutex);
std::function<void()> task;
if (!taskList.isEmpty())
{
task = taskList.first();
lock.unlock();
task();
qDebug() << "done Worker" << thread();
}
}
用法
ThreadPool::getInstance()->addTask([]()
{
QThread::sleep(3);
}, 0);
ThreadPool::getInstance()->addTask([]()
{
QThread::sleep(3);
}, 0);
ThreadPool::getInstance()->addTask([]()
{
QThread::sleep(10);
});
ThreadPool::getInstance()->addTask([]()
{
QThread::sleep(10);
});
|