Qt-Qt版本线程池实现

#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();//默认5个线程
    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
        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);
});
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
在Qt中,可以使用QThreadPool类来实现线程池线程池是一种管理和复用线程的机制,可以有效地管理线程资源,提高程序的并发性能。 要使用线程池,首先需要创建一个继承自QRunnable的任务类,并实现run()函数,在run()函数中编写需要在子线程中执行的代码。然后,可以通过调用QThreadPool::globalInstance()获取全局的线程池实例,并调用start()函数将任务添加到线程池中执行。 下面是一个简单的示例代码,演示如何使用线程池实现均值滤波: ```c #include <QCoreApplication> #include <QThreadPool> #include <QDebug> // 继承自QRunnable的任务类 class FilterTask : public QRunnable { public: FilterTask(int* data, int size) : m_data(data), m_size(size) { } void run() override { // 执行均值滤波操作 int sum = 0; for (int i = 0; i < m_size; i++) { sum += m_data[i]; } int average = sum / m_size; qDebug() << "Average: " << average; } private: int* m_data; int m_size; }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); int data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int dataSize = sizeof(data) / sizeof(data[0]); // 创建任务对象 FilterTask task(data, dataSize); // 添加任务到线程池中执行 QThreadPool::globalInstance()->start(&task); return a.exec(); } ``` 在上面的示例中,我们创建了一个继承自QRunnable的任务类FilterTask,它接收一个整型数组和数组大小作为参数,在run()函数中计算数组的均值并输出。 然后,我们在主函数中创建了一个整型数组data,并获取其大小。接着,创建了一个FilterTask对象task,并调用QThreadPool::globalInstance()->start()函数将任务添加到线程池中执行。 运行程序,可以看到在子线程中执行了均值滤波操作,并打印出了结果。 相关问题: 1. 除了QThreadPool,Qt中还有其他实现线程池的类吗? 2. 如何设置线程池的最大线程数和最小空闲线程数? 3. 线程池的优势是什么?为什么要使用线程池而不是直接创建线程? 4. 在Qt中如何处理线程池中的任务完成信号? 5. 线程池适用于哪些场景?有什么注意事项?

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mrbone11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值