[gelöst]QThreads: Welche Invarianten gelten für Threads?

Alles rund um die Programmierung mit Qt
Antworten
Konfusious
Beiträge: 2
Registriert: 6. November 2007 23:49

[gelöst]QThreads: Welche Invarianten gelten für Threads?

Beitrag von Konfusious »

Seit ein paar Tagen beschäftige ich mich mit QT, und muss sagen, das es wirklich eine schöne Bibliothek ist.

Allerdings bin ich gerade in der Sackgasse, und wollte bevor ich jetzt den Quellcode von QT durchackere erst noch bei euch nach fragen.

Folgende Situation:

Ich habe eine kleine Anwendung die einen Thread konstruiert und aufruft.
Komischer weise stürzt die Anwendung ab. Rufe ich die run()-Methode des Threads manuell auf (um zu prüfen ob der code darin korrekt ist), funktioniert alles wie es soll, nur eben ohne Thread.

Das interessante im Fehlerfall (also nicht run() manuell aufrufen) ist das dass letzte Statement vor thread->start() ausgeführt wird, aber das erste Satement (simple logging-Ausgabe) innerhalb von Thread::run() nicht mehr ausgeführt wird.

Daraus folgere ich das es nicht an meiner run()-Methode liegt, sondern das während der Ausführung der start()-Methode etwas passiert das meine Anwendung abstürzen lässt.

Daher meine Frage: Woran muss ich mich halten wenn ich eine Thread-Klasse programmiere. Das ich run() überschreiben muss ist klar. Ebenso das ich den Thread mit start() starte. Genauso wie das der Thread natürlich von QThread erben muss.
Dateianhänge
OnixParser.h
Thread-Klasse
(2.32 KiB) 70-mal heruntergeladen
Zuletzt geändert von Konfusious am 7. November 2007 17:55, insgesamt 1-mal geändert.
CaptnChaos
Beiträge: 605
Registriert: 28. Juni 2007 15:01
Kontaktdaten:

Beitrag von CaptnChaos »

In run musst du exec() aufrufen, um die Thread Loop zu starten.
Oder du packst alles was in run ist in eine unendliche while-Schleife.
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Das mit 'exec()' ist Käse... Was macht m_handler? Ich vermute, daß es an der Übergabe zu m_handler schon scheitert. Setz mal dort einen Breakpoint und laß das ganze im Debugger laufen.
CaptnChaos
Beiträge: 605
Registriert: 28. Juni 2007 15:01
Kontaktdaten:

Beitrag von CaptnChaos »

Nö, isses net.....
Zu dem m_handler: es gibt immer Probleme wenn du in einem zweiten Thread auf Objekte des Main-Threads zugreifst, ich denke das machst du hier.
Wenn du das Programm in der Konsole(bzw unter Windows ein Debugmessage-Abfang Programm laufen lässt, zb DgbView von SysInternals) startest wird es irgendeine Warnung ausspucken, die das besagt.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

KernelPanic hat recht

Code: Alles auswählen

m_handler->printStatusMessage("entered run()");
Erzeugt unter Garantie ein PaintEvent. Da dies nicht im Main(==Gui)Thread ist, kann es nicht funktionieren da nur dieser zeichnen darf.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Konfusious
Beiträge: 2
Registriert: 6. November 2007 23:49

Beitrag von Konfusious »

Ich bin dem Ganzen jetzt ein wenig auf den Grund gegangen, und habe es interesanter Weise irgendwie gelöst.

Zunächst einmal:
1. Alle Threads einer Anwendung teilen sich den selben Heap-Speicher. Das bedeutet das mit new alozierte Objekte einfach innerhalb des Thread genutzt werden können.

2. Jeder Thread hat aber einen eigenen Stack, was dazu führt, das Objekte die nicht mit new aloziert wurden Probleme machen können.

3. exec() muss nur aufgerufen werden, wenn der Thread eine eigene EventLoop benötigt, also z.B auf Signale reagieren können soll. Für einfache Operationen die nebenläufig arbeiten und keine Signale empfangen oder versenden ist der Aufruf von exec() unnötig.

4. Ich hatte meine Thread-Klasse auf dem Stack erzeugt (also ohne new). Dies führte zu meinen Abstürzen. Nachdem ich die Thread-Klasse auf dem Heap erzeugt habe, lief alles prima.


Um also meine eigene Frage zu beantworten: Thread-Klassen müssen auf dem Heap mittels new erzeugt werden.

So, ich hoffe das dass anderen weiterhelfen kann. Euch vielen Dank für die Impulse und Lösungsansätze.
Antworten