C++ 线程在Qt中的应用
我正在学习Qt中的线程管理,如果我犯了一些小错误,请向我道歉。让我们回到话题上来 简短描述:C++ 线程在Qt中的应用,c++,multithreading,qt,C++,Multithreading,Qt,我正在学习Qt中的线程管理,如果我犯了一些小错误,请向我道歉。让我们回到话题上来 简短描述: #ifndef WORKER_H #define WORKER_H #include <QObject> #include <QMutex> class Worker : public QObject { Q_OBJECT public: explicit Worker(QObject *parent = nullptr); void stop();
#ifndef WORKER_H
#define WORKER_H
#include <QObject>
#include <QMutex>
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QObject *parent = nullptr);
void stop();
void setMessage(const QString &message);
signals:
void finished();
public slots:
void process();
private:
volatile bool stopped;
QString messageStr;
QMutex mutex;
};
#endif // WORKER_H
#include "worker.h"
#include <QDebug>
Worker::Worker(QObject *parent)
: QObject(parent)
{
stopped = false;
}
void Worker::process()
{
forever
{
mutex.lock();
if(stopped)
{
stopped = false;
mutex.unlock();
break;
}
mutex.unlock();
qDebug() << messageStr;
}
emit finished();
}
void Worker::stop()
{
mutex.lock();
stopped = true;
mutex.unlock();
}
void Worker::setMessage(const QString &message)
{
messageStr = message;
}
#ifndef MYDIALOG_H
#define MYDIALOG_H
#include <QDialog>
class Worker;
class MyDialog : public QDialog
{
Q_OBJECT
public:
MyDialog(QWidget *parent = nullptr);
private slots:
void startStopThreadA();
void startStopThreadB();
void showWorkingGUI();
private:
Worker *workerA;
Worker *workerB;
QThread *threadA;
QThread *threadB;
QPushButton *threadAButton;
QPushButton *threadBButton;
QPushButton *quitButton;
};
#endif // MYDIALOG_H
#include "mydialog.h"
#include "worker.h"
#include <QCloseEvent>
#include <QHBoxLayout>
#include <QPushButton>
#include <QThread>
#include <QDebug>
#include <QTimer>
MyDialog::MyDialog(QWidget *parent)
: QDialog(parent)
{
//Here bla bla for gui
threadAButton = new QPushButton(tr("Start A"));
threadBButton = new QPushButton(tr("Start B"));
quitButton = new QPushButton(tr("Quit"));
connect(threadAButton, SIGNAL(clicked()), this, SLOT(startStopThreadA()));
connect(threadBButton, SIGNAL(clicked()), this, SLOT(startStopThreadB()));
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(threadAButton);
layout->addWidget(threadBButton);
layout->addWidget(quitButton);
setLayout(layout);
//Create worker's instances
workerA = new Worker;
workerB = new Worker;
workerA->setMessage("Thread 1");
workerB->setMessage("Thread 2");
//Create threads instances
threadA = new QThread;
threadB = new QThread;
//Move worker to thread
workerA->moveToThread(threadA);
workerB->moveToThread(threadB);
connect(threadA, SIGNAL(started()), workerA, SLOT(process()));
connect(workerA, SIGNAL(finished()), threadA, SLOT(quit()));
connect(workerA, SIGNAL(finished()), workerA, SLOT(deleteLater()));
connect(threadA, SIGNAL(finished()), threadA, SLOT(deleteLater()));
connect(threadB, SIGNAL(started()), workerB, SLOT(process()));
connect(workerB, SIGNAL(finished()), threadB, SLOT(quit()));
connect(workerB, SIGNAL(finished()), workerB, SLOT(deleteLater()));
connect(threadB, SIGNAL(finished()), threadB, SLOT(deleteLater()));
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(showWorkingGUI()));
timer->start(1000);
}
void MyDialog::startStopThreadA()
{
if(threadA->isRunning())
{
workerA->stop();
threadAButton->setText(tr("Start A"));
}
else
{
threadA->start();
threadAButton->setText(tr("Stop A"));
}
}
void MyDialog::startStopThreadB()
{
if(threadB->isRunning())
{
workerB->stop();
threadBButton->setText(tr("Start B"));
}
else
{
threadB->start();
threadBButton->setText(tr("Stop B"));
}
}
void MyDialog::showWorkingGUI()
{
qDebug() << "GUI Thread works!";
}
#include <QApplication>
#include "mydialog.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyDialog dialog;
dialog.show();
return a.exec();
}
我编写了一个测试线程如何工作的小应用程序。我有两个按钮的简单GUI界面。它们可以启动和停止不同的线程。线程基于下的工作者类。我正在使用Ubuntu 16.04 LTS x64下的Qt Creator编译代码
主要问题:
#ifndef WORKER_H
#define WORKER_H
#include <QObject>
#include <QMutex>
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QObject *parent = nullptr);
void stop();
void setMessage(const QString &message);
signals:
void finished();
public slots:
void process();
private:
volatile bool stopped;
QString messageStr;
QMutex mutex;
};
#endif // WORKER_H
#include "worker.h"
#include <QDebug>
Worker::Worker(QObject *parent)
: QObject(parent)
{
stopped = false;
}
void Worker::process()
{
forever
{
mutex.lock();
if(stopped)
{
stopped = false;
mutex.unlock();
break;
}
mutex.unlock();
qDebug() << messageStr;
}
emit finished();
}
void Worker::stop()
{
mutex.lock();
stopped = true;
mutex.unlock();
}
void Worker::setMessage(const QString &message)
{
messageStr = message;
}
#ifndef MYDIALOG_H
#define MYDIALOG_H
#include <QDialog>
class Worker;
class MyDialog : public QDialog
{
Q_OBJECT
public:
MyDialog(QWidget *parent = nullptr);
private slots:
void startStopThreadA();
void startStopThreadB();
void showWorkingGUI();
private:
Worker *workerA;
Worker *workerB;
QThread *threadA;
QThread *threadB;
QPushButton *threadAButton;
QPushButton *threadBButton;
QPushButton *quitButton;
};
#endif // MYDIALOG_H
#include "mydialog.h"
#include "worker.h"
#include <QCloseEvent>
#include <QHBoxLayout>
#include <QPushButton>
#include <QThread>
#include <QDebug>
#include <QTimer>
MyDialog::MyDialog(QWidget *parent)
: QDialog(parent)
{
//Here bla bla for gui
threadAButton = new QPushButton(tr("Start A"));
threadBButton = new QPushButton(tr("Start B"));
quitButton = new QPushButton(tr("Quit"));
connect(threadAButton, SIGNAL(clicked()), this, SLOT(startStopThreadA()));
connect(threadBButton, SIGNAL(clicked()), this, SLOT(startStopThreadB()));
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(threadAButton);
layout->addWidget(threadBButton);
layout->addWidget(quitButton);
setLayout(layout);
//Create worker's instances
workerA = new Worker;
workerB = new Worker;
workerA->setMessage("Thread 1");
workerB->setMessage("Thread 2");
//Create threads instances
threadA = new QThread;
threadB = new QThread;
//Move worker to thread
workerA->moveToThread(threadA);
workerB->moveToThread(threadB);
connect(threadA, SIGNAL(started()), workerA, SLOT(process()));
connect(workerA, SIGNAL(finished()), threadA, SLOT(quit()));
connect(workerA, SIGNAL(finished()), workerA, SLOT(deleteLater()));
connect(threadA, SIGNAL(finished()), threadA, SLOT(deleteLater()));
connect(threadB, SIGNAL(started()), workerB, SLOT(process()));
connect(workerB, SIGNAL(finished()), threadB, SLOT(quit()));
connect(workerB, SIGNAL(finished()), workerB, SLOT(deleteLater()));
connect(threadB, SIGNAL(finished()), threadB, SLOT(deleteLater()));
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(showWorkingGUI()));
timer->start(1000);
}
void MyDialog::startStopThreadA()
{
if(threadA->isRunning())
{
workerA->stop();
threadAButton->setText(tr("Start A"));
}
else
{
threadA->start();
threadAButton->setText(tr("Stop A"));
}
}
void MyDialog::startStopThreadB()
{
if(threadB->isRunning())
{
workerB->stop();
threadBButton->setText(tr("Start B"));
}
else
{
threadB->start();
threadBButton->setText(tr("Stop B"));
}
}
void MyDialog::showWorkingGUI()
{
qDebug() << "GUI Thread works!";
}
#include <QApplication>
#include "mydialog.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyDialog dialog;
dialog.show();
return a.exec();
}
#ifndef WORKER_H
#define WORKER_H
#include <QObject>
#include <QMutex>
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QObject *parent = nullptr);
void stop();
void setMessage(const QString &message);
signals:
void finished();
public slots:
void process();
private:
volatile bool stopped;
QString messageStr;
QMutex mutex;
};
#endif // WORKER_H
#include "worker.h"
#include <QDebug>
Worker::Worker(QObject *parent)
: QObject(parent)
{
stopped = false;
}
void Worker::process()
{
forever
{
mutex.lock();
if(stopped)
{
stopped = false;
mutex.unlock();
break;
}
mutex.unlock();
qDebug() << messageStr;
}
emit finished();
}
void Worker::stop()
{
mutex.lock();
stopped = true;
mutex.unlock();
}
void Worker::setMessage(const QString &message)
{
messageStr = message;
}
#ifndef MYDIALOG_H
#define MYDIALOG_H
#include <QDialog>
class Worker;
class MyDialog : public QDialog
{
Q_OBJECT
public:
MyDialog(QWidget *parent = nullptr);
private slots:
void startStopThreadA();
void startStopThreadB();
void showWorkingGUI();
private:
Worker *workerA;
Worker *workerB;
QThread *threadA;
QThread *threadB;
QPushButton *threadAButton;
QPushButton *threadBButton;
QPushButton *quitButton;
};
#endif // MYDIALOG_H
#include "mydialog.h"
#include "worker.h"
#include <QCloseEvent>
#include <QHBoxLayout>
#include <QPushButton>
#include <QThread>
#include <QDebug>
#include <QTimer>
MyDialog::MyDialog(QWidget *parent)
: QDialog(parent)
{
//Here bla bla for gui
threadAButton = new QPushButton(tr("Start A"));
threadBButton = new QPushButton(tr("Start B"));
quitButton = new QPushButton(tr("Quit"));
connect(threadAButton, SIGNAL(clicked()), this, SLOT(startStopThreadA()));
connect(threadBButton, SIGNAL(clicked()), this, SLOT(startStopThreadB()));
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(threadAButton);
layout->addWidget(threadBButton);
layout->addWidget(quitButton);
setLayout(layout);
//Create worker's instances
workerA = new Worker;
workerB = new Worker;
workerA->setMessage("Thread 1");
workerB->setMessage("Thread 2");
//Create threads instances
threadA = new QThread;
threadB = new QThread;
//Move worker to thread
workerA->moveToThread(threadA);
workerB->moveToThread(threadB);
connect(threadA, SIGNAL(started()), workerA, SLOT(process()));
connect(workerA, SIGNAL(finished()), threadA, SLOT(quit()));
connect(workerA, SIGNAL(finished()), workerA, SLOT(deleteLater()));
connect(threadA, SIGNAL(finished()), threadA, SLOT(deleteLater()));
connect(threadB, SIGNAL(started()), workerB, SLOT(process()));
connect(workerB, SIGNAL(finished()), threadB, SLOT(quit()));
connect(workerB, SIGNAL(finished()), workerB, SLOT(deleteLater()));
connect(threadB, SIGNAL(finished()), threadB, SLOT(deleteLater()));
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(showWorkingGUI()));
timer->start(1000);
}
void MyDialog::startStopThreadA()
{
if(threadA->isRunning())
{
workerA->stop();
threadAButton->setText(tr("Start A"));
}
else
{
threadA->start();
threadAButton->setText(tr("Stop A"));
}
}
void MyDialog::startStopThreadB()
{
if(threadB->isRunning())
{
workerB->stop();
threadBButton->setText(tr("Start B"));
}
else
{
threadB->start();
threadBButton->setText(tr("Stop B"));
}
}
void MyDialog::showWorkingGUI()
{
qDebug() << "GUI Thread works!";
}
#include <QApplication>
#include "mydialog.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyDialog dialog;
dialog.show();
return a.exec();
}
worker.h:
#ifndef WORKER_H
#define WORKER_H
#include <QObject>
#include <QMutex>
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QObject *parent = nullptr);
void stop();
void setMessage(const QString &message);
signals:
void finished();
public slots:
void process();
private:
volatile bool stopped;
QString messageStr;
QMutex mutex;
};
#endif // WORKER_H
#include "worker.h"
#include <QDebug>
Worker::Worker(QObject *parent)
: QObject(parent)
{
stopped = false;
}
void Worker::process()
{
forever
{
mutex.lock();
if(stopped)
{
stopped = false;
mutex.unlock();
break;
}
mutex.unlock();
qDebug() << messageStr;
}
emit finished();
}
void Worker::stop()
{
mutex.lock();
stopped = true;
mutex.unlock();
}
void Worker::setMessage(const QString &message)
{
messageStr = message;
}
#ifndef MYDIALOG_H
#define MYDIALOG_H
#include <QDialog>
class Worker;
class MyDialog : public QDialog
{
Q_OBJECT
public:
MyDialog(QWidget *parent = nullptr);
private slots:
void startStopThreadA();
void startStopThreadB();
void showWorkingGUI();
private:
Worker *workerA;
Worker *workerB;
QThread *threadA;
QThread *threadB;
QPushButton *threadAButton;
QPushButton *threadBButton;
QPushButton *quitButton;
};
#endif // MYDIALOG_H
#include "mydialog.h"
#include "worker.h"
#include <QCloseEvent>
#include <QHBoxLayout>
#include <QPushButton>
#include <QThread>
#include <QDebug>
#include <QTimer>
MyDialog::MyDialog(QWidget *parent)
: QDialog(parent)
{
//Here bla bla for gui
threadAButton = new QPushButton(tr("Start A"));
threadBButton = new QPushButton(tr("Start B"));
quitButton = new QPushButton(tr("Quit"));
connect(threadAButton, SIGNAL(clicked()), this, SLOT(startStopThreadA()));
connect(threadBButton, SIGNAL(clicked()), this, SLOT(startStopThreadB()));
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(threadAButton);
layout->addWidget(threadBButton);
layout->addWidget(quitButton);
setLayout(layout);
//Create worker's instances
workerA = new Worker;
workerB = new Worker;
workerA->setMessage("Thread 1");
workerB->setMessage("Thread 2");
//Create threads instances
threadA = new QThread;
threadB = new QThread;
//Move worker to thread
workerA->moveToThread(threadA);
workerB->moveToThread(threadB);
connect(threadA, SIGNAL(started()), workerA, SLOT(process()));
connect(workerA, SIGNAL(finished()), threadA, SLOT(quit()));
connect(workerA, SIGNAL(finished()), workerA, SLOT(deleteLater()));
connect(threadA, SIGNAL(finished()), threadA, SLOT(deleteLater()));
connect(threadB, SIGNAL(started()), workerB, SLOT(process()));
connect(workerB, SIGNAL(finished()), threadB, SLOT(quit()));
connect(workerB, SIGNAL(finished()), workerB, SLOT(deleteLater()));
connect(threadB, SIGNAL(finished()), threadB, SLOT(deleteLater()));
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(showWorkingGUI()));
timer->start(1000);
}
void MyDialog::startStopThreadA()
{
if(threadA->isRunning())
{
workerA->stop();
threadAButton->setText(tr("Start A"));
}
else
{
threadA->start();
threadAButton->setText(tr("Stop A"));
}
}
void MyDialog::startStopThreadB()
{
if(threadB->isRunning())
{
workerB->stop();
threadBButton->setText(tr("Start B"));
}
else
{
threadB->start();
threadBButton->setText(tr("Stop B"));
}
}
void MyDialog::showWorkingGUI()
{
qDebug() << "GUI Thread works!";
}
#include <QApplication>
#include "mydialog.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyDialog dialog;
dialog.show();
return a.exec();
}
\ifndef WORKER\u H
#定义WORKER_H
#包括
#包括
班级工作人员:公共QObject
{
Q_对象
公众:
显式工作者(QObject*parent=nullptr);
无效停止();
无效设置消息(常量字符串和消息);
信号:
无效完成();
公众时段:
无效过程();
私人:
挥发性bool停止;
QString消息str;
QMutex互斥;
};
#endif//WORKER\u H
worker.cpp:
#ifndef WORKER_H
#define WORKER_H
#include <QObject>
#include <QMutex>
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QObject *parent = nullptr);
void stop();
void setMessage(const QString &message);
signals:
void finished();
public slots:
void process();
private:
volatile bool stopped;
QString messageStr;
QMutex mutex;
};
#endif // WORKER_H
#include "worker.h"
#include <QDebug>
Worker::Worker(QObject *parent)
: QObject(parent)
{
stopped = false;
}
void Worker::process()
{
forever
{
mutex.lock();
if(stopped)
{
stopped = false;
mutex.unlock();
break;
}
mutex.unlock();
qDebug() << messageStr;
}
emit finished();
}
void Worker::stop()
{
mutex.lock();
stopped = true;
mutex.unlock();
}
void Worker::setMessage(const QString &message)
{
messageStr = message;
}
#ifndef MYDIALOG_H
#define MYDIALOG_H
#include <QDialog>
class Worker;
class MyDialog : public QDialog
{
Q_OBJECT
public:
MyDialog(QWidget *parent = nullptr);
private slots:
void startStopThreadA();
void startStopThreadB();
void showWorkingGUI();
private:
Worker *workerA;
Worker *workerB;
QThread *threadA;
QThread *threadB;
QPushButton *threadAButton;
QPushButton *threadBButton;
QPushButton *quitButton;
};
#endif // MYDIALOG_H
#include "mydialog.h"
#include "worker.h"
#include <QCloseEvent>
#include <QHBoxLayout>
#include <QPushButton>
#include <QThread>
#include <QDebug>
#include <QTimer>
MyDialog::MyDialog(QWidget *parent)
: QDialog(parent)
{
//Here bla bla for gui
threadAButton = new QPushButton(tr("Start A"));
threadBButton = new QPushButton(tr("Start B"));
quitButton = new QPushButton(tr("Quit"));
connect(threadAButton, SIGNAL(clicked()), this, SLOT(startStopThreadA()));
connect(threadBButton, SIGNAL(clicked()), this, SLOT(startStopThreadB()));
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(threadAButton);
layout->addWidget(threadBButton);
layout->addWidget(quitButton);
setLayout(layout);
//Create worker's instances
workerA = new Worker;
workerB = new Worker;
workerA->setMessage("Thread 1");
workerB->setMessage("Thread 2");
//Create threads instances
threadA = new QThread;
threadB = new QThread;
//Move worker to thread
workerA->moveToThread(threadA);
workerB->moveToThread(threadB);
connect(threadA, SIGNAL(started()), workerA, SLOT(process()));
connect(workerA, SIGNAL(finished()), threadA, SLOT(quit()));
connect(workerA, SIGNAL(finished()), workerA, SLOT(deleteLater()));
connect(threadA, SIGNAL(finished()), threadA, SLOT(deleteLater()));
connect(threadB, SIGNAL(started()), workerB, SLOT(process()));
connect(workerB, SIGNAL(finished()), threadB, SLOT(quit()));
connect(workerB, SIGNAL(finished()), workerB, SLOT(deleteLater()));
connect(threadB, SIGNAL(finished()), threadB, SLOT(deleteLater()));
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(showWorkingGUI()));
timer->start(1000);
}
void MyDialog::startStopThreadA()
{
if(threadA->isRunning())
{
workerA->stop();
threadAButton->setText(tr("Start A"));
}
else
{
threadA->start();
threadAButton->setText(tr("Stop A"));
}
}
void MyDialog::startStopThreadB()
{
if(threadB->isRunning())
{
workerB->stop();
threadBButton->setText(tr("Start B"));
}
else
{
threadB->start();
threadBButton->setText(tr("Stop B"));
}
}
void MyDialog::showWorkingGUI()
{
qDebug() << "GUI Thread works!";
}
#include <QApplication>
#include "mydialog.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyDialog dialog;
dialog.show();
return a.exec();
}
#包括“worker.h”
#包括
工作者::工作者(QObject*父)
:QObject(父对象)
{
停止=错误;
}
void Worker::process()
{
永远
{
mutex.lock();
如果(停止)
{
停止=错误;
mutex.unlock();
打破
}
mutex.unlock();
qDebug()addWidget(threadAButton);
布局->添加小部件(线程按钮);
布局->添加小部件(退出按钮);
设置布局(布局);
//创建工人的实例
workerA=新员工;
workerB=新员工;
workerA->setMessage(“线程1”);
workerB->setMessage(“线程2”);
//创建线程实例
threadA=新的QThread;
threadB=新的QThread;
//将工作线程移动到线程
workerA->moveToThread(threadA);
workerB->moveToThread(threadB);
连接(线程A、信号(已启动())、工作区、插槽(进程());
连接(工作区、信号(完成())、线程A、插槽(退出());
连接(workerA,信号(finished()),workerA,插槽(deleteLater());
连接(threadA、信号(finished())、threadA、插槽(deleteLater());
连接(螺纹B、信号(已启动())、工件B、插槽(进程());
连接(workerB、信号(finished())、螺纹b、插槽(quit());
连接(workerB,信号(finished()),workerB,插槽(deleteLater());
连接(threadB,信号(finished()),threadB,插槽(deleteLater());
QTimer*定时器=新的QTimer(此);
连接(计时器、信号(超时())、此、插槽(showWorkingGUI());
定时器->启动(1000);
}
void MyDialog::startStopThreadA()
{
如果(threadA->isRunning())
{
workerA->stop();
threadAButton->setText(tr(“开始A”);
}
其他的
{
threadA->start();
threadAButton->setText(tr(“停止A”);
}
}
void MyDialog::startStopThreadB()
{
如果(threadB->isRunning())
{
workerB->stop();
线程按钮->设置文本(tr(“开始B”);
}
其他的
{
threadB->start();
线程按钮->设置文本(tr(“停止B”);
}
}
void MyDialog::showWorkingGUI()
{
qDebug()在button方法中创建新对象,而不是MyDialog
ctor解决了我的问题。例如:
void MainWindow::startStopThreadA()
{
//First method - start/stop thread
if(threadA && threadA->isRunning())
{
workerA->stop();
threadA = nullptr;
ui->threadAButton->setText("Start A");
}
else
{
threadA = new QThread;
workerA = new WorkerObject;
workerA->setMessage("Thread A running");
workerA->moveToThread(threadA);
connect(threadA, SIGNAL(started()), workerA, SLOT(process()), Qt::QueuedConnection);
connect(workerA, SIGNAL(finished()), threadA, SLOT(quit()));
connect(workerA, SIGNAL(finished()), workerA, SLOT(deleteLater()));
connect(threadA, SIGNAL(finished()), threadA, SLOT(deleteLater()));
threadA->start();
ui->threadAButton->setText("Stop A");
}
}
当我尝试启动线程时,它工作正常。然后我停止它并尝试重新启动。在这种情况下,线程不会启动。可能我正在以正确的方式关闭线程?我想你只能启动一个线程1次。你可能想强制此连接(threadA,SIGNAL(start()),workerA,SLOT(process());
使用Qt::QueuedConnection
“volatile bool stopped;”-注意:volatile
并不意味着线程安全。您可能希望atomic
在那里。线程停止后会被破坏。因此,在释放threadA
后,如果(threadA->isRunning())调用。MyDialog::startStopThreadA()
如果需要,可以使用@JesperJuhl提供的有关原子线程的建议创建一个新线程,以确定它是否已停止。