Verständnisfrage zu QMutex

Alles rund um die Programmierung mit Qt
Antworten
101
Beiträge: 72
Registriert: 16. Januar 2008 16:28

Verständnisfrage zu QMutex

Beitrag von 101 »

Hallo,

ich habe ein kleines Verständnisproblem mit QMutex.

Ich habe eine Anwendung mit GUI. In einem Thread werden Daten von einer Schnittstelle eingelesen und in eine QHash geschrieben. Die GUI greift über einen Timer auf diese Daten zu, um die Inhalte zu visualisieren.

Meine Frage: benötige ich einen QMutex, um die Daten zu locken (es schreibt nur eine Instanz die Daten)? Wenn ja, muss dieser Mutex Global sein, oder reicht ein lokaler Mutex im Thread?
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Re: Verständnisfrage zu QMutex

Beitrag von pfid »

101 hat geschrieben:Hallo,

ich habe ein kleines Verständnisproblem mit QMutex.

Ich habe eine Anwendung mit GUI. In einem Thread werden Daten von einer Schnittstelle eingelesen und in eine QHash geschrieben. Die GUI greift über einen Timer auf diese Daten zu, um die Inhalte zu visualisieren.

Meine Frage: benötige ich einen QMutex, um die Daten zu locken (es schreibt nur eine Instanz die Daten)? Wenn ja, muss dieser Mutex Global sein, oder reicht ein lokaler Mutex im Thread?
Wenn 2 Threads auf das gleiche Objekt zugreifen, brauchst du immer ein Mutex, es sei denn beide Lesen lediglich, und keiner schreibt.

WO das Mutex ist, ist wurscht. Wichtig ist nur, dass beide Threads das gleiche Mutex-Objekt sperren. (also ist es egal, ob dus statisch, global, im gui-thread oder im worker-thread liegen hast)
101
Beiträge: 72
Registriert: 16. Januar 2008 16:28

Beitrag von 101 »

Also generiere ich z.B. in meiner GUI ein Mutex Objekt und übergebe dem Thread bei der Instanziierung einen Pointer auf dieses Objekt. Wäre dies die richtige Vorgehensweise? Muss man beim Lesen und Schreiben den Mutex locken / unlocken?
Superheftig
Beiträge: 63
Registriert: 6. September 2008 15:20

Beitrag von Superheftig »

Ja dann hast du das gleiche QMutex Objetkt in beiden threads.

Am besten du nimmst einen QMutexLocker zum locken...dann kann es dir nicht passieren, dass du ihn vergisst zu unlocken und nen deadlock bekommst.

Code: Alles auswählen

QMutexLocker locker(myMutex);
Wenn du mehrere Threads hast die lesen kannst du auch ne QReadWriteLock nehmen
101
Beiträge: 72
Registriert: 16. Januar 2008 16:28

Beitrag von 101 »

Ich denke ich werde QReadWriteLock verwenden.
Spricht etwas dagegen? Wie sieht es da aus mit dem Blockieren der GUI, wenn größere Datenmengen vom Thread geschrieben werden?
Superheftig
Beiträge: 63
Registriert: 6. September 2008 15:20

Beitrag von Superheftig »

Musst du halt schauen das der Thread nicht zu lange am stück den mutex lockt...sonst friert die gui ein.
Also wenn du wirklich viele daten auf einmal hast solltest du das schreiben in kleinere Teile unterteilen und dazwischen immer nen kurzes msleep(1) einbauen.
Ich würds aber erstmal ohne probieren.
101
Beiträge: 72
Registriert: 16. Januar 2008 16:28

Beitrag von 101 »

Wie sieht es eigentlich bei einem Zugriff (lesend/schreibend) auf z.B. 16 Bit Variablen aus. Kann es da eigentlich zu Kollisionen kommen? Ich denke mal die Lese bzw. Schreiboperation der CPU wird in einem Prozessortakt ausgeführt? Inkonsistenzen der Daten dürften hier eigentlich nicht vorkommen, oder habe ich hier einen Denkfehler?
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

101 hat geschrieben:Wie sieht es eigentlich bei einem Zugriff (lesend/schreibend) auf z.B. 16 Bit Variablen aus. Kann es da eigentlich zu Kollisionen kommen? Ich denke mal die Lese bzw. Schreiboperation der CPU wird in einem Prozessortakt ausgeführt? Inkonsistenzen der Daten dürften hier eigentlich nicht vorkommen, oder habe ich hier einen Denkfehler?
Allgemeingültig - nein
Auf den Plattformen auf denen du vermutlich unterwegs bist - ja

So könnte man es grob sagen.

[edit] Das mit dem msleep würde ich übrigens eher lassen, das ist unzuverlässig und nicht im Sinne der Sache. Das würde ich dann eher mit ner wait condition lösen.
101
Beiträge: 72
Registriert: 16. Januar 2008 16:28

Beitrag von 101 »

Ich gehe mal von einem 32Bit Prozessor aus.
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

Also generiere ich z.B. in meiner GUI ein Mutex Objekt und übergebe dem Thread bei der Instanziierung einen Pointer auf dieses Objekt. Wäre dies die richtige Vorgehensweise?
In einem Thread werden Daten von einer Schnittstelle eingelesen und in eine QHash geschrieben.
Du willst mit dem Mutex deine "Daten", in deinem Falle die QHash schuetzen. Ne gute Idee waere, den Mutex gleich neben oder mit dem QHash zu erzeugen. Ich wuerde es zumindest erwarten, wenn ich in dem Code was suchen sollte.
Richtige (vielleicht auch uebertriebene) OO rangehensweisse waere, deine Daten, also den QHash inklusive den Mutex zu kapseln, mit nem Interface versehen, was angepasst ist auf die art und weisse wie auf deine Daten zugreifst.
Ich denke ich werde QReadWriteLock verwenden.
Spricht etwas dagegen?
Prinzipiell geht nen ReadWriteLocker auch .... der hat aber bissi mehr overhaed als wie nen reiner mutex wahrscheinlich (iss eh alles QT implementationsdetail).
Nen ReadWriteLocker macht eigentlich nur Sinn, wenn mehrere Threads gleichzeitig lesend lesend auf die Daten zugreifen koennten, und mit einem oder mehreren schreibenden Threads gesynct werden muessen.
Bei der Klassischen Konstellation, genau ein schreibender, und genau ein Lesender Thread macht das ding keinen Sinn.
Der Unterschied ist also, das bei nem readwritelocker mehrere threads grad lesend in der kritischen section unterwegs sind, waehrend bei nem normalen mutex immer nur einer in der section sein kann, egal was er tut.
Deswegen ist der ReadwriteLocker eigentlich kein Mutex mehr.

Wie sieht es eigentlich bei einem Zugriff (lesend/schreibend) auf z.B. 16 Bit Variablen aus
Auf dem ersten Blick, kein problem .... aufn zweiten Block scho ^^
Nen compiler kann optimieren, und das koennte dir immer nen strich durch die rechnung machen. nen 16Bit wert wird bei ner rechenopration wahrscheinlich auf nen 32bit wert aufgebohrt. da wird aus einer offensichtlichen rechenoperation schon mal mehr.

Die meisten BS bieten aber genau dafuer expliziete atomare operationen an, die garantieren das es zu keinen so nebeneffekten kommt. Genau diese werden fuer die implementationen der Synchronisationsobjecte dann verwendet.

Ciao ...
Antworten