Qt-线程队列

开发过程中,一些运算耗时比较长的任务,我们会将其放在线程中运行。

任务前提

从网络上传来了大量的图片,我们短时间内会接收很多,但是处理图片的时间比接受时间长的多。

处理步骤

1.首先我们创建一个任务管理类,用于管理任务的信息

task.h

#ifndef TASK_H
#define TASK_H

#include <QImage>
/*
* 用于管理任务的所有信息
* 也可以内部处理
*/
class Task
{
public:
    Task(QImage image,QString path);

    bool saveImage();
    QString path();

private:
    QImage m_image;//将要保存的图片
    QString m_strSavePath;//保存
};

#endif // TASK_H

task.cpp

#include "task.h"

#include <QDebug>
Task::Task(QImage image,QString path)
    : m_image(image)
    , m_strSavePath(path)
{

}

bool Task::saveImage()
{
    bool ret = true;
//    if(!m_image.isNull()&& !m_strSavePath.isEmpty()){
//        ret = m_image.save(m_strSavePath);
//    }
    qDebug()<<"执行完毕";
    return ret;
}

QString Task::path(){

    return m_strSavePath;
}

2.创建线程,用于添加任务并处理

workThread.h

#ifndef WORKTHREAD_H
#define WORKTHREAD_H

#include <QThread>
#include <QMutex>
//线程任务队列
class Task;
class workThread : public QThread
{
    Q_OBJECT
public:
    workThread(QObject *parent = 0);
    void run();
    void addTask(Task *task); //添加任务在最前面,最后添加的优先级最高
    void stop(){ m_bStart = false;}

    Task *popTask();
signals:
    void sigWorkfinish(QString);

private:
    QList<Task *>m_taskList;// 任务列表
    QMutex m_mutex;
    bool m_bStart = true;
};


#endif // WORKTHREAD_H

workthread.cpp

/*
*@brief:循环执行任务的线程队列
* @author:swang
*/
#include "workthread.h"
#include "task.h"

workThread::workThread(QObject * parent)
    :QThread(parent)
    ,m_bStart(true)
{

}
void workThread::run()
{
    while (m_bStart) {

        Task * task = popTask();
        if(task){
            if(task->saveImage()){
                emit sigWorkfinish(task->path());
                delete task;
                task = nullptr;
            }
        }
        msleep(1000);
    }
}
//新增任务,可以采用头插法或者尾插法,注意加锁
void workThread::addTask(Task *task)
{
    m_mutex.lock();
    m_taskList.push_front(task);//头插
    //m_taskList.push_back(task);//尾插
    m_mutex.unlock();
}

//取出任务,每次取链表的第一个值
Task *workThread::popTask()
{
    m_mutex.lock();
    Task *task;
    if(0 == m_taskList.size())
    {
        task = nullptr;
    }
    else
    {
        task = m_taskList.takeFirst();
    }
    m_mutex.unlock();
    return task;
}

在这里,我们创建了一个线程,采用头插法,将任务插入任务list中,注意取出任务时也是取得头元素

m_taskList.push_front(task);

3.调用

MainWindow.cpp

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , pworkThread(new workThread(this))
{
    ui->setupUi(this);

    pworkThread->start();

    QImage image;

    for(int i = 0; i< 100; i++)
    {
        pworkThread->addTask(new Task(image,"ss"));
    }
    connect(pworkThread,&workThread::sigWorkfinish,[=](QString s){
        qDebug()<<s;
    });
}

MainWindow::~MainWindow()
{
    pworkThread->stop();
    pworkThread->quit();
    pworkThread->wait();
    delete ui;
}

源码

https://download.csdn.net/download/yonggandess/12594412

猜你喜欢

转载自blog.csdn.net/yonggandess/article/details/107227435