QThread: Distrutto mentre il thread è ancora in esecuzione?

Vorrei iniziare il mio QThread quando premo sul pulsante Eseguire. Ma il compilatore uscite seguente errore:

QThread: Destroyed while thread is still running
ASSERT failure in QThread::setTerminationEnabled(): "Current thread was not started with QThread.", file thread\qthread_win.cp.

Non so che cosa è sbagliato con il mio codice.

Qualsiasi aiuto sarebbe apprezzato.

Ecco il mio codice:

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;
}
Il SamplingThread è creata nella prima riga del MainWindow::start, poi ha iniziato, quindi immediatamente distrutto mentre è ancora in esecuzione come il start restituisce. Il messaggio di errore ti dice cosa c’è di sbagliato, e C++ semantica dirvi perché è così. Questa domanda non ha molto a che fare con Qt, tutti a che fare con la comprensione della semantica di un linguaggio di programmazione che si sta utilizzando.

InformationsquelleAutor The Man | 2014-07-26

3 Replies
  1. 20

    Come il messaggio di errore indica: QThread: Destroyed while thread is still running. La creazione di SamplingThread oggetto all’interno del MainWindow::start metodo, ma va al di fuori dell’ambito (cioè è distrutto) quando il metodo termina. Ci sono due semplici modi che vedo:

    1. Rendere il vostro SamplingThread un membro della vostra MainWindow quindi la sua durata è la stessa per il MainWindow istanza
    2. Si utilizza un puntatore, cioè si crea il SamplingThread utilizzando

      SamplingThread *samplingThread = new SamplingThread;

    Aiutare?

    Edit: per illustrare i due casi, molto grezzo esempio per mostrare i due casi

    #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();
    }
    Per la soluzione. 2. si può tranquillamente prendere quello che ho scritto. È quindi necessario sostituire il ‘.’ accede all’oggetto da ‘->’ per accedere ai metodi dell’oggetto sottostante (se questo non significa nulla per te, io consiglio vivamente di passare attraverso alcuni più c++ tutorial di base e.g alcuni di quelli suggeriti qui stackoverflow.com/questions/388242/…). 1:non so il codice del tuo MainWindow ma in generale di dichiarare l’oggetto ad esempio come membro privato classe e quindi inizializzare in un en.cppreference.com/w/cpp/language/initializer_list
    Di nuovo, se non sai quello che un membro di una classe, si dovrebbe davvero leggere di più su questo (e.g qui per scegliere una delle molte molte possibilità: cplusplus.com/doc/tutorial/classes). Se si va il secondo modo è impostare solo la frequenza e chiamare il metodo run in MainWindow::metodo di avvio come l’oggetto è stato creato già nella lista di inizializzazione
    naturalmente , io Noto che membro della classe o come posso accedere a un metodo, in realtà , il mio commento non era per te , ho un’altra domanda su questo forum e volevo il codice. anway grazie per il link sul libro
    Grazie. la sua ora funziona bene.. ho una domanda di carattere generale ora, io non utilizzato per inizializzare tutti i membri della mia classe come te prima di usarlo . è pericoloso ?
    Grazie, questa è completo.

    InformationsquelleAutor Erik

  2. 4

    Questo è basi del C++! La creazione di locali oggetto di QThread su stack non heap, in modo che si ottiene distrugge immediatamente quando si lascia metodo MainWindow::start.

    Dovrebbe essere fatto così:

    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);
    }

    InformationsquelleAutor Marek R

  3. 2

    Ci sono due diverse “thread” coinvolti: Uno è l’attuale filo, l’altro è il C++ oggetto che rappresenta (e per essere corretto, c’è un altro thread che questo codice è iniziato in primo luogo).

    L’errore dice solo che il thread è ancora in esecuzione nel punto in cui il C++ oggetto che rappresenta è distrutto. Nel codice, il motivo è che il QThread istanza locale start(). Forse si desidera memorizzare il QThread in un membro.

    InformationsquelleAutor Ulrich Eckhardt

Lascia un commento