说明:在复现过程中出现两点问题(1)run()函数中对m_diceValued的赋值(2)do_timeOut()函数中没有对m_seq、m_diceValued进行定义。修改后的复现程序如下所示:
主线程:
.h
- #pragma once
-
- #include
- #include "ui_ThreadTest_one.h"
- #include "QtClass.h"
-
- class ThreadTest_one : public QMainWindow//主线程
- {
- Q_OBJECT
-
- private:
- QtClass* threadA;
- QTimer* timer;//新定义定时器
-
- protected:
- void closeEvent(QCloseEvent* event);
-
-
- public:
- ThreadTest_one(QWidget* parent = nullptr);
- ~ThreadTest_one();
-
- private:
- Ui::ThreadTest_oneClass ui;
-
- public slots:
- void do_threadA_started();
- void do_threadA_finished();
-
- void on_actThread_Run_clicked();
- void on_actDice_Run_clicked();
- void on_actThread_Quit_clicked();
- void on_actDict_Pause_clicked();
- void do_timeOut();//新增定时器槽函数
-
- };
.cpp
- #include "ThreadTest_one.h"
- #include <QCloseEvent>
- #include <QThread>
- #include <QTimer>
-
-
- ThreadTest_one::ThreadTest_one(QWidget *parent)
- : QMainWindow(parent)
- {
- ui.setupUi(this);
- threadA = new QtClass(this);//创建工作线程
- connect(threadA, &QtClass::started, this, &ThreadTest_one::do_threadA_started);
- connect(threadA, &QtClass::finished, this, &ThreadTest_one::do_threadA_finished);
- timer = new QTimer(this);
- timer->setInterval(200);
- connect(timer, &QTimer::timeout, this, &ThreadTest_one::do_timeOut);
-
- }
-
- void ThreadTest_one::do_timeOut() {
- int tmpSeq = 0, tmpValue = 1;
- int m_diceValue;
- static int m_seq = 0;
- bool valid = threadA->readValue(&tmpSeq, &tmpValue);//地址做实参,值会改变
- if (valid&&(tmpSeq!=m_seq&&tmpSeq!=0)) {
- m_seq = tmpSeq;
- m_diceValue = tmpValue;
- QString str = QString::asprintf("第%d次投骰子,点数为:%d",m_seq,m_diceValue);
- ui.plainTextEdit->appendPlainText(str);
- }
- }
-
- void ThreadTest_one::do_threadA_started() {
- ui.statusBar->showMessage("Thread状态:thread start");
- ui.actThread_Run->setEnabled(false);
- ui.actThread_Quit->setEnabled(true);
- ui.actDice_Run->setEnabled(true);
-
- }
- void ThreadTest_one::do_threadA_finished() {
- ui.statusBar->showMessage("Thread状态:thread finished");
- ui.actThread_Run->setEnabled(true);
- ui.actThread_Quit->setEnabled(false);
- ui.actDice_Run->setEnabled(false);
- ui.actDict_Pause->setEnabled(false);
- }
-
- //按键的槽函数
- void ThreadTest_one::on_actThread_Run_clicked() {//要用clicked才能得到响应
- threadA->start();
- }
- void ThreadTest_one::on_actThread_Quit_clicked() {
- threadA->stopThread();
- }
- void ThreadTest_one::on_actDice_Run_clicked() {
- threadA->diceBegin();
- timer->start();
- ui.actDice_Run->setEnabled(false);
- ui.actDict_Pause->setEnabled(true);
- }
- void ThreadTest_one::on_actDict_Pause_clicked() {
- threadA->dicePause();
- timer->stop();
- ui.actThread_Run->setEnabled(true);
- ui.actDict_Pause->setEnabled(false);
- }
-
- //重定义事件处理函数,确保窗口关闭时线程被停止
- void ThreadTest_one::closeEvent(QCloseEvent* event) {
- if (threadA->isRunning()) {
- threadA->terminate();
- threadA->wait();
- }
- event->accept();
- }
-
- ThreadTest_one::~ThreadTest_one()
- {}
工作线程:
.h
- #pragma once
-
- #include
- #include
-
- class QtClass : public QThread
- {
- Q_OBJECT
-
- public:
- QtClass(QObject *parent);
- ~QtClass();
- private:
- int m_seq = 0; //掷骰子次数的序号
- int m_diceValue;//骰子的点数
- bool m_paused = true;//暂停投骰子
- bool m_stop = false;//停止线程
- QMutex mutex;//基于互斥量的线程同步,定义一个互斥量
-
- protected:
- void run();//线程的任务,线程的事件循环
-
- public:
- void diceBegin();//开始掷骰子
- void dicePause();//暂停投骰子
- void stopThread();//停止线程
- bool readValue(int *seq, int *diceValue);//供主线程读取数据的函数
-
- };
.cpp
- #include "QtClass.h"
- #include<QRandomGenerator>
- #include<QThread>
-
- QtClass::QtClass(QObject *parent)
- : QThread(parent)
- {}
- void QtClass::diceBegin() {//开始掷骰子
- m_paused = false;
- }
- void QtClass::dicePause() {//停止掷骰子
- m_paused = true;
- }
- void QtClass::stopThread() {//停止线程
- m_stop = true;
- }
- void QtClass::run() {//run函数处理事件循环
- m_stop = false;
- m_paused = true;
- m_seq = 0;
- while (!m_stop) {
- if (!m_paused) {
- mutex.lock();//锁定互斥量
- m_diceValue = 0;
- //for(int i=0;i<5;i++)
- m_diceValue = QRandomGenerator::global()->bounded(1, 7);
- //m_diceValue = m_diceValue / 5;
- m_seq++;
- mutex.unlock();//解锁互斥量
- }
- msleep(500);
- }
- quit();//退出线程
- }
- bool QtClass::readValue(int* seq, int* diceValue) {
- if (mutex.tryLock(100)) {
- *seq = m_seq;
- *diceValue = m_diceValue;
-
- mutex.unlock();
- return true;
- }
- else
- return false;
- }
-
- QtClass::~QtClass()
- {}