我必须按两个不同的按钮开始/停止一个线程 请建议我的代码是否正确。我是否在connect()调用中遗漏了一些内容?
Problem
我面临的是,在我的线程上调用quit()之后,我等待我的线程完成,但是在线程never returns true
上调用wait(),以及我的{{1} ,而(!m_deviceThread.wait())
请建议如何解决此问题?
我的devicethread& Mainwindow类中定义的worker对象: -
program is stuck in
主设备线程对象:-----
QThread m_deviceThread;
deviceThreadObject *m_deviceThreadObject;
deviceThreadObject对象构造函数: -
class deviceThreadObject : public QObject
{
Q_OBJECT
public:
explicit deviceThreadObject(QObject *parent = 0);
/*!
Termination control main thread
*/
bool m_bQuit;
signals:
public slots:
void dowork();
};
我有按下按钮开始运行的主线程// constructor for the deviceThreadObject
deviceThreadObject::deviceThreadObject(QObject *parent) :
QObject(parent)
{
m_bQuit = false;
}
:---
m_deviceThread
我有主线程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
//设备的公共插槽 - 线程
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";
}
}
答案 0 :(得分:2)
我过去曾见过几种不同的方法。
下面显示了编译器优化代码的内容:
bool quit = false;
while(!quit)
{
// no reference to quit here or in any functions mentioned in here
}
可能会变成一个永远的循环。
// bool quit = false
while(true)
{
// looks the same to the compiler...
}
强制您了解线程同步和关键区域或互斥或信号量的最佳做法是将对quit参数的访问视为线程之间共享的变量,并将其包装,以便只能由一个线程访问它。时间。我首选的方法是使用QMutexLocker
,因为它可以很好地处理范围更改,return
s,break
等等。
http://qt-project.org/doc/qt-5.1/qtcore/qmutexlocker.html#details
所以你的代码得到了这样的补充:
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
。它不是推荐的做法,并且在编译器之间不可靠。
希望有所帮助。