如何停止线程 - Qthread [英] How to stop thread - Qthread
问题描述
我必须按两个不同的按钮来启动/停止一个线程.
请建议我的代码是否正确.我是否错过了 connect() 调用中的某些内容?
I have to start/stop a thread on press of two different buttons.
Please suggest my code is correct or not. Do I have missed something in the connect() call ?
问题
我面临的是在我的线程上调用 quit() 之后,然后我等待我的线程完成,但是线程上的 wait() 调用 永远不会返回 true
, 而我的 程序卡在
, while(!m_deviceThread.wait())
Problem
i am facing is that after calling quit() on my thread, then i wait for my thread to finish, but wait() call on thread never returns true
, and my program is stuck in
, while(!m_deviceThread.wait())
请建议如何解决这个问题?
Please suggest how to resolve this ?
我的设备线程 &在 Mainwindow 类中定义的 worker 对象:--
My devicethread & worker object defined in Mainwindow class :--
QThread m_deviceThread;
deviceThreadObject *m_deviceThreadObject;
主设备线程对象:-----
Main device thread object :-----
class deviceThreadObject : public QObject
{
Q_OBJECT
public:
explicit deviceThreadObject(QObject *parent = 0);
/*!
Termination control main thread
*/
bool m_bQuit;
signals:
public slots:
void dowork();
};
deviceThreadObject 对象构造函数:--
deviceThreadObject object constructor :--
// constructor for the deviceThreadObject
deviceThreadObject::deviceThreadObject(QObject *parent) :
QObject(parent)
{
m_bQuit = false;
}
我有主线程 m_deviceThread
在按下按钮开始时运行:---
I have main thread m_deviceThread
which runs on button start pressed:---
void MainWindow::on_actionStart_triggered()
{
if(!b_threadAlreadyStarted)
{
m_deviceThreadObject = new deviceThreadObject;
// connect device thread signal to the slot
connect(&m_deviceThread ,SIGNAL(started()),m_deviceThreadObject,SLOT(dowork()));
m_deviceThreadObject->moveToThread(&m_deviceThread);
// Set the flag before starting slot of main thread
m_deviceThreadObject->m_bQuit = true;
m_deviceThread.start();
}
}
我有主线程 m_deviceThread
在按下按钮停止时停止:---
I have main thread m_deviceThread
which stops on button stop pressed:---
void MainWindow::on_actionStop_triggered()
{
if(b_threadAlreadyStarted)
{
b_threadAlreadyStarted = false;
// get out of event loop
m_deviceThreadObject->m_bQuit = false;
m_deviceThread.quit();
qDebug() << " \n quit ";
// wait for thread to terminate
while(!m_deviceThread.wait());
m_deviceThreadObject->deleteLater();
qDebug() << " \n finished";
}
}
//设备的公共槽——线程
// Common slot for the Device - thread
void deviceThreadObject::dowork()
{
while(m_bquit)
{
// Do some work
}
}
推荐答案
我过去见过几种不同的方法来做到这一点.
I've seen a few different ways to do this in the past.
下面展示了编译器优化你的代码的样子:
Below is showing what the compiler optimizes your code to look like:
bool quit = false;
while(!quit)
{
// no reference to quit here or in any functions mentioned in here
}
可能会变成一个永远的循环.
could get turned into just a forever loop.
// bool quit = false
while(true)
{
// looks the same to the compiler...
}
强制您了解线程同步和关键区域或互斥体或信号量的最佳实践是将退出参数的访问视为线程之间共享的变量,并将其包装起来,以便一次只能由一个线程访问时间.我的首选方法是使用 QMutexLocker
,因为它可以很好地处理范围更改、return
s、break
s 等.
The best practice that forces you to know thread synchronization and critical areas or mutexs or semaphores, is to treat the access to the quit parameter as a variable shared between threads, and wrap it so it is only accessed by one thread at a time. My preferred method is to use a QMutexLocker
, since it handles well with scope changes, return
s, break
s, etc.
http://qt-project.org/doc/qt-5.1/qtcore/qmutexlocker.html#details
所以你的代码得到了这样的补充:
So your code gets the additions like this:
deviceThreadObject::deviceThreadObject(QObject *parent) :
QObject(parent)
{
m_mutex = new QMutex();
}
void deviceThreadObject::stop()
{
QMutexLocker locker(m_mutex);
m_stopped = true;
}
void deviceThreadObject::doWork()
{
m_stopped = false;
while(true)
{
// The core work of your thread...
// Check to see if we were stopped
{
QMutexLocker locker(m_mutex);
if(m_stopped)
break;
}// locker goes out of scope and releases the mutex
}
}
一个快速而肮脏的捷径是使用 volatile bool
.这不是推荐的做法,并且在编译器中也不可靠.
A quick and dirty shortcut is to use a volatile bool
. It is not a recommended practice, and isn't as reliable across compilers.
希望有所帮助.
这篇关于如何停止线程 - Qthread的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!