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;

【问题讨论】:

SamplingThreadMainWindow::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:线程仍在运行时被销毁?的主要内容,如果未能解决你的问题,请参考以下文章

QThread:在线程仍在运行时被销毁

Qt:qthread在关闭期间线程仍在运行时被破坏

QProcess 和 shell:进程仍在运行时被销毁

QtConcurrent::run => QWaitCondition: 在线程仍在等待时被销毁

UITableViewDelegate dealloc 方法在应用程序仍在运行时被调用

如果在其他线程仍在运行时调用exit会发生什么?