QThread:线程仍在运行时被销毁?
Posted
技术标签:
【中文标题】QThread:线程仍在运行时被销毁?【英文标题】:QThread: Destroyed while thread is still running? 【发布时间】:2014-09-18 01:20:48 【问题描述】:当我按下按钮运行时,我想启动我的QThread
。但是编译器输出如下错误:
QThread: Destroyed while thread is still running
ASSERT failure in QThread::setTerminationEnabled(): "Current thread was not started with QThread.", file thread\qthread_win.cp.
我不知道我的代码有什么问题。
任何帮助将不胜感激。
这是我的代码:
SamplingThread::SamplingThread( QObject *parent):
QwtSamplingThread( parent ),
d_frequency( 5.0 )
init();
MainWindow::MainWindow( QWidget *parent ):
QMainWindow( parent )
.......
.....
run= new QPushButton ("Run",this);
stop= new QPushButton("Stop",this);
connect(run, SIGNAL(clicked()),this, SLOT (start()));
MainWindow::start
SamplingThread samplingThread;
samplingThread.setFrequency( frequency() );
samplingThread.start();
int main( int argc, char **argv )
QApplication app( argc, argv );
MainWindow window;
window.resize( 700, 400 );
window.show();
bool ok = app.exec();
return ok;
【问题讨论】:
SamplingThread
在MainWindow::start
的第一行创建,然后启动,然后在start
返回时立即销毁当它仍在运行时。错误消息告诉你出了什么问题,C++ 语义告诉你为什么会这样。这个问题与 Qt 没有太大关系,全都与您对所使用的编程语言的语义的理解有关。
【参考方案1】:
如错误消息所述:QThread: Destroyed while thread is still running
。您正在 MainWindow::start
方法内创建您的 SamplingThread
对象,但是当该方法终止时它超出范围(即被销毁)。我看到了两种简单的方法:
-
您将
SamplingThread
设为MainWindow
的成员,因此其生命周期与MainWindow
实例的生命周期相同
您使用指针,即您使用
创建SamplingThread
SamplingThread *samplingThread = new SamplingThread;
这有帮助吗?
编辑:为了说明这两种情况,一个非常粗略的例子来展示这两种情况
#include <iostream>
#include <QApplication>
#include <QThread>
class Dummy
public:
Dummy();
void start();
private:
QThread a;
;
Dummy::Dummy() :
a()
void Dummy::start()
a.start();
QThread *b = new QThread;
b->start();
if( a.isRunning() )
std::cout << "Thread a is running" << std::endl;
if( b->isRunning() )
std::cout << "Thread b is running" << std::endl;
int main(int argc, char** argv)
QApplication app(argc,argv);
Dummy d;
d.start();
return app.exec();
【讨论】:
用于解决方案。 2.你几乎可以接受我写的东西。然后,您必须替换“。”通过 '->' 访问对象以访问底层对象的方法(如果这对您没有任何意义,我强烈建议您阅读更多的 c++ 基础教程,例如这里建议的一些教程***.com/questions/388242/…)。对于 1:我不知道您的 MainWindow 的代码,但通常您声明对象,例如作为您的班级的私人成员,然后在 en.cppreference.com/w/cpp/language/initializer_list 中对其进行初始化 再一次,如果你不知道一个类的成员是什么,你真的应该阅读更多关于这个的内容(例如在这里选择许多可能性之一:cplusplus.com/doc/tutorial/classes)。如果您采用第二种方式,您只需设置频率并在 MainWindow::start 方法中调用 run 方法,因为该对象已在初始化列表中创建 当然,我知道班级成员是什么或我如何访问方法,实际上,我的评论不是给你的,我在这个论坛上有另一个问题,我想要代码。无论如何感谢您提供有关这本书的链接 谢谢。它现在工作正常。我现在有一个一般性问题,我以前不像你那样初始化我班级的所有成员来使用它。危险吗? 谢谢,这已经完成了。【参考方案2】:这是 C++ 的基础!您正在堆栈而不是堆上创建 QThread
的本地对象,因此当您离开方法 MainWindow::start
时它会立即销毁。
应该这样做:
MainWindow::MainWindow( QWidget *parent ):
QMainWindow( parent )
...
samplingThread = SamplingThread(this);
samplingThread->setFrequency( frequency() );
run= new QPushButton ("Run",this);
stop= new QPushButton("Stop",this);
connect(run, SIGNAL(clicked()), samplingThread, SLOT(start()));
MainWindow::~MainWindow()
samplingThread->waitFor(5000);
【讨论】:
【参考方案3】:涉及两个不同的“线程”:一个是实际线程,另一个是代表它的 C++ 对象(正确地说,还有另一个线程首先启动此代码)。
错误只是说线程仍在运行,表示它的 C++ 对象被销毁。在您的代码中,原因是 QThread 实例是 start()
的本地实例。也许您想将 QThread 存储在成员中。
【讨论】:
以上是关于QThread:线程仍在运行时被销毁?的主要内容,如果未能解决你的问题,请参考以下文章
QtConcurrent::run => QWaitCondition: 在线程仍在等待时被销毁