QT学习记录(三)如何终止QThreadPool内线程以及反馈后台线程任务完成提示

在项目中我采用了QThreadPool使用多线程,但是因为线程操作的是临界资源,所以在我需要保证下一次短时间内的任务更改生效,我必须先停止之前线程未完成的操作步骤,即停止线程内的后台任务。
***********************************分割线------------------------------------------
任务类头文件

#ifndef TASK_H
#define TASK_H

#include <QRunnable>
#include <QObject>

class Task : public QObject,public QRunnable { 
//多继承,为了前者为了信号和槽函数连接,后者为了配合QThreadPool
    Q_OBJECT

public:
    Task();
    ~Task();
    void run() Q_DECL_OVERRIDE;

public slots:
    void setCancel();
private:
    bool m_isstop;
signals:
    void load_over();
};

#endif // TASK_H

任务实现

#include "task.h"
#include <QDebug>
#include <QDateTime>

Task::Task() :m_isstop(false) {
}

Task::~Task() {
    qDebug().noquote() << QString("~Task() with ID %1").arg(m_id); // 方便查看对象是否被 delete
}


void Task::run() {
	for(int i = 0;i < 10000;i++)
	{
		if(m_isstop)
        {
            qDebug()<<"Stop thread Work. thread ID:"<<QThread::currentThreadId();
            break;//退出任务
        }
		sleep(10000000);//耗时操作
	}
    emit load_over();//发送完成信号
}

void Task::setCancel()
{
    m_isstop = true;//收到取消信号后改变bool变量
}

主操作界面头文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QThread>
#include <QThreadPool>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    QThreadPool *Q_pool;
    Task *task;
    
private slots:
    void on_pushButton_clicked();//开始按键
    void on_pushButton1_clicked();//停止按键

private:
    Ui::MainWindow *ui;
signals:
    void stop();
public slots:
    void over();
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <fstream>
#include <iostream>
using namespace std;
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
    m_workThread.quit();
    m_workThread.wait();
}

void MainWindow::over()
{
    ui->pushButton->setEnabled(true);
}

void MainWindow::on_pushButton_clicked()//开启线程
{
	ui->pushButton->setEnabled(false);//取消按键使能避免多个加入多个线程
	Q_pool = new QThreadPool();
    Q_pool->setMaxThreadCount(1);
	Task *task = new Task(filename);
    connect(this,SIGNAL(stop()),task,SLOT(setCancel()));
    connect(task,SIGNAL(load_over()),this,SLOT(over()));
    Q_pool->globalInstance()->start(task);
}
void MainWindow::on_pushButton1_clicked()//停止线程
{
    emit stop();
    ui->pushButton->setEnabled(true);
}
void MainWindow::start(int i)
{
    qDebug()<<"num:"<<i<<endl;
    emit start_work(i);
}

***********************************分割线------------------------------------------
tips:若QRunnable未设置deleteauto属性为false,则交由线程池进行释放
在这里插入图片描述

最终实现效果如下:
1.开启线程任务前

在这里插入图片描述
2.开启线程任务后台运行时
在这里插入图片描述
3.点击stop按键或者线程任务结束后
在这里插入图片描述
心得:在项目中因为是在解析文件写入数据到一个数据库,因为写入时间较长,为避免用户操作过快,上一个写入还未完成便开启下个无关文件的数据载入造成数据错乱或者数据库连接过多,所以通过这种槽函数和信号的机制避开极端情况

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值