2016-08-09 130 views
1

Ich versuche Qthread mit einem Objekt zu verwenden. Zu diesem Zweck wird dieser Code geschrieben:Was passiert, wenn ich deleterater nicht zum Löschen von qthread verwende?

QThread *thread1 = new QThread(); 
serialclass *obje = new serialclass(); 
void MainWindow::on_pushButton_baglan_clicked() 
{ 
    obje->moveToThread(thread1); 
    connect(thread1,SIGNAL(started()),obje,SLOT(baglan()), Qt::UniqueConnection); 
    connect(obje,SIGNAL(finished()),thread1,SLOT(quit())); //end of the baglan function finished() signal is emitted. 
    thread1->start(); 
} 

Mein Code funktioniert. Aber ich benutzte quit(), nicht deleterater(). Die Taste kann sehr oft gedrückt werden. Die erste Frage ist, ist diese Methode wahr? Meine zweite Frage ist, was passiert, wenn ich den Knopf viel Zeit drücke. Gibt es viel Faden? Wird jedes Mal ein Thread erstellt?

Antwort

0

Das ist in Ordnung. Sie sollten verstehen, was Sie tun und warum: Der Code und sein Zweck sollten von Ihnen und von einem solchen Verständnis stammen.

Wenn Sie die Taste eine Menge Zeit drücken, könnte die Anwendung in einem von zwei Zuständen sein:

  1. Der Thread bereits beendet: obje->thread() == nullptr und Sie den Faden sind Neustarten - es wird funktionieren .

  2. Der Thread läuft noch: obje->thread() == thread1 und beide moveToThread und thread1->start() nichts tun.

Leider hat es keinen Sinn, den Thread zu stoppen. Es hat eine Ereignisschleife, die blockiert wird, bis neue Ereignisse ankommen, es ist nicht so, als ob ein Leerlauf QThread irgendeine CPU verbraucht. Das Starten eines Threads ist teuer: Er erstellt einen neuen nativen Thread. Ein fertiger Thread hört auf zu existieren: Ja, Sie haben immer noch eine QThread, aber das ist wie ein Handle zu einer geschlossenen Datei. QThread ist schließlich ein Thread-Handle.

Sie sollten Ihre Mitglieder nach Wert, nicht per Zeiger halten - das vermeidet die dumme vorzeitige Pessimierung der zusätzlichen Indirektion über einen Punkt. Sie können alle Verbindungen im Voraus einrichten. Sie benötigen den Steckplatz on_pushButton_baglan_clicked() nicht: Sie können die Drucktaste direkt mit der Instanz SerialClass verbinden. Sie sollten auch eine QThread-abgeleitete Klasse verwenden, die sicher zerstörbar ist.

Ihr Code kann wie folgt aussehen. Der Compiler wird einen geeigneten Destruktor zum Entfernen von Ressourcen für Sie generieren. Es ist die Aufgabe des Compilers, und es wird Ihnen in diesem Job niemals fehlen - während ein menschlicher Entwickler sehr anfällig für Fehler ist. So sollten Sie RAII zu Ihrem Vorteil nutzen, da es ein Dienstbote manuelle Arbeit auf die Maschine verlagert, die es perfekt tun und für so gut wie nichts :)

// MyWindow.h 
#include <QMainWindow> 
#include <QThread> 
#include "SerialClass.h" 
#include "ui_MyWindow.h" 

class MyWindow : public QMainWindow { 
    Q_OBJECT 
    class SafeThread : public QThread { 
    using QThread::run; // final 
    public: 
    ~SafeThread() { quit(); wait(); } 
    } m_serialThread; 
    SerialClass m_serial; 
    Ui::MyWindow ui; 
public: 
    MyWindow(QWidget * parent = nullptr); 
}; 

// MyWindow.cpp 
#include "MyWindow.h" 

MyWindow::MyWindow(QWidget * parent) : 
    QMainWindow{this} 
{ 
    ui.setupUi(this); 
    connect(ui.pushButton_baglan, &QPushButton::clicked, 
      &m_serial, &SerialClass::baglan); 
    m_serial.moveToThread(&m_serialThread); 
    m_serialThread.start(); 
} 

Wenn Sie nicht alle Details der Implementierung tun wollen leben in MyWindow Kopfzeile, Sie should use a PIMPL.