web-dev-qa-db-ja.com

QThread:スレッドの実行中に破棄されましたか?

ボタンを押したときに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;
}
8
The Man

エラーメッセージが示すように:QThread: Destroyed while thread is still runningMainWindow::startメソッド内にSamplingThreadオブジェクトを作成していますが、そのメソッドが終了するとスコープ外になります(つまり、破棄されます)。私が見る2つの簡単な方法があります:

  1. SamplingThreadMainWindowのメンバーにするので、その存続期間はMainWindowインスタンスの場合と同じです。
  2. ポインタを使用します。つまり、を使用してSamplingThreadを作成します。

    SamplingThread *samplingThread = new SamplingThread;

これは役に立ちますか?

編集:2つのケースを説明するために、2つのケースを示す非常に大雑把な例

#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();
}
22
Erik

これが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);
}
5
Marek R

関連する2つの異なる「スレッド」があります。1つは実際のスレッドであり、もう1つはそれを表すC++オブジェクトです(正確には、このコードが最初に開始される別のスレッドがあります)。

エラーは、スレッドを表すC++オブジェクトが破棄された時点でスレッドがまだ実行中であることを示しています。あなたのコードでは、その理由は、QThreadインスタンスがstart()に対してローカルであるためです。 QThreadをメンバーに保存したい場合があります。

2
Ulrich Eckhardt