QThread: finished-signale kommen nicht an

Alles rund um die Programmierung mit Qt
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

1. Da das connect() im Context des Hauptthreads (QApplication) ausgeführt wird - siehe alle möglichen Diskussionen zum Thema Thread-Programmierung hier im Forum.
2. Diese Funktion wird im Context das MainThreads (deines Verwaltungsthreads) ausgeführt. Gleiche Begründung wie in 1.
3. Ja, da muss ein Mutex rein - es darf nicht gleichzeitig gelesen und geschrieben werden

Nochwas zu 1. und 2.
QThread ist nicht der Thread sondern nur ein Hilfsobjekt zum Verwalten eines Threads. Ein QThread-Objekt 'lebt' dort wo es erzeugt wird. Also 'lebt' der MainThread im Hauptthread und demnach werden auch dort die Signals/Slots ausgeführt. Alle Subthreads leben im MainThread - also werden alle Signals/Slots dieser Threads im MainThread ausgeführt und auch die GUI-Operationen. Deshalb ist das falsch. Hier erklärt sich auch warum es am Anfang nicht so funktionierte wie gewünscht und man sieht auch dass die Subthreads (in der hier gezeigten Version) keine Eventloop brauchen.

Ich sehe übrigens genausowenig wie solarix Sinn für den MainThread...
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
graythornAK
Beiträge: 29
Registriert: 16. März 2007 15:14

Beitrag von graythornAK »

Ok, danke euch, jetzt habe ich das mit der eventloop und den threads verstanden. :wink:

Christian81 hat geschrieben: Ich sehe übrigens genausowenig wie solarix Sinn für den MainThread...
Zur Erklärung:
es handelt sich um ein Gafikprogram.
Der App()-Thread ist für die Darstellung des Bildes in einem Fenster zuständig. Die Bildbearbeitung erfolgt über Kommandos die jeweils in einem Thread laufen.

1) Einfacher Filter, z.B. Das Bild spiegeln:

Das geht zügig. Die App() startet das Kommando, dieses läuft in einem Thread. Ist es fertig wird die App() davon unterichtet und das Ergebnis angezeigt.


2) Ein komplexer Filter, z.B. Eine Fourier/Laplace Transformation mit weiteren Oparationen auf das Bild -> lange Laufzeit

In diesem Fall wird das entsprechende Kommando abgesetzt, die App() kümmert sich um das enablen/disablen von Menupunkten, resize-events etc.
Das Kommando (der Mainthread) zerteilt jetzt die Arbeit auf "kacheln", also einzelne Bildbereiche, die sich nicht überschneiden. Diese werden auf neue Threads (subThreads) verteilt. Abhängig vom Ergebnis der subthreads werden dann weitere Kacheln gerechnet, bzw. bereits gerechnete Kacheln weiter verarbeitet.

Ist das ein so dummes Konzept?

Hinzu kommt, das auf bereits bestehende Klassen (Kommandos) zurückgegriffen werden muß, die dieses Konzept vorgeben.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Schau dir einfach mal zum Spaß QtConcurrent::mapped() und QtConcurrent::mappedReduced() an :)
// edit: Und einfache Threads startest du dann mit QtConcurrent::run()
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Ok, das hört sich an als wäre es eine Anwenundgsmöglichkeit.
Vielleicht bietet sich da auch http://doc.trolltech.com/4.7/threads-qtconcurrent.html an. Und QThread::idealThreadCount() zu beachten bietet sich auch an.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

kann franzf und Christian81 nur recht geben: das ist eine typische Anwendung für QtConcurrent. Übrigens beachtet QtConcurrent::run() den idealThreadCount bereits.. d.h. man kann einfach alle Operationen starten und Qt verteilt es optimal auf die zur Verfügung stehenden Cores :wink:

Siehe auch
ftp://ftp.qt.nokia.com/videos/DevDays20 ... urrent.pdf

hth..
graythornAK
Beiträge: 29
Registriert: 16. März 2007 15:14

Beitrag von graythornAK »

solarix hat geschrieben: ...das ist eine typische Anwendung für QtConcurrent.
Ja, sieht so aus :D


Noch mal ne dumme Frage (bin halt "Thread-Neuling") :roll:

Ich habe Bilddaten, also einen Speicherbereich für das komplette Bild. Diese Adresse (also auf den Anfang des Speicherbeiches, ich übergebe eine Referenz auf den Startpointer) gebe ich allen subthreads mit. Diese bearbeiten jetzt einen garantiert anderen Bereich dieses Speicherbereiches lesend und schreibend als alle anderen SubThreads,

also etwa:

Code: Alles auswählen

char  *pBuffer = new char[1000];

new subthread1(pBuffer, 0, 100);
new subthread2(pBuffer, 100, 100);
new subthread3(pBuffer, 200, 100);
...

class SubThread
{
    SubThread(char   *&_bufStart,
                     int      _iOffset,
                     int      _iLen)
    {
        ... lese und schreibe im Puffer ab _iOffset und max _iLen bytes
    }
...
}
brauche ich hier irgendwelch mutexe???
Ich meine nein.....
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

graythornAK hat geschrieben:brauche ich hier irgendwelch mutexe???
Ich meine nein.....
Ich meine: Das kommt nicht auf SubThreads an, sondern auch auf MainThread. Wie du oben geschrieben hast (und ich auch schon um Korrektheit meiner Annahme gefragt habe), greift der auch auf den Speicher zu - zwar nur lesend, aber das ist bei einem gleichzeitigen schreibenden Zugriff aus SubThread wurscht!
Prinzipiell: Wenn kein ReadOnly-Speicher vorliegt und verschiedene Threads gleichzeitig schreibend und lesend drauf zugreifen könnten, muss der Bereich geschützt werden!
graythornAK
Beiträge: 29
Registriert: 16. März 2007 15:14

Beitrag von graythornAK »

franzf hat geschrieben:
graythornAK hat geschrieben:brauche ich hier irgendwelch mutexe???
Ich meine nein.....
Ich meine: Das kommt nicht auf SubThreads an, sondern auch auf MainThread. Wie du oben geschrieben hast (und ich auch schon um Korrektheit meiner Annahme gefragt habe), greift der auch auf den Speicher zu - zwar nur lesend, aber das ist bei einem gleichzeitigen schreibenden Zugriff aus SubThread wurscht!
Prinzipiell: Wenn kein ReadOnly-Speicher vorliegt und verschiedene Threads gleichzeitig schreibend und lesend drauf zugreifen könnten, muss der Bereich geschützt werden!
Sorry, ich vergaß zu erwähnen, das MainThread jetzt NICHT MEHR lesend auf den Speicher zugreift. Lediglich die subthreads greifen lesend/schreibend auf ihre jeweiligen Blöcke.

Daher denke ich, ich brauche keine Mutexe mehr, oder?
Antworten