Seite 1 von 1

Verständnisfrage zu QMutex

Verfasst: 1. Juli 2009 14:24
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?

Re: Verständnisfrage zu QMutex

Verfasst: 1. Juli 2009 14:40
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)

Verfasst: 1. Juli 2009 14:50
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?

Verfasst: 1. Juli 2009 15:06
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

Verfasst: 1. Juli 2009 15:32
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?

Verfasst: 1. Juli 2009 16:07
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.

Verfasst: 1. Juli 2009 16:14
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?

Verfasst: 1. Juli 2009 16:26
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.

Verfasst: 1. Juli 2009 16:30
von 101
Ich gehe mal von einem 32Bit Prozessor aus.

Verfasst: 2. Juli 2009 09:52
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 ...