Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Boolean-Variablen in TThread
Gausi - Do 02.07.09 10:44
Titel: Boolean-Variablen in TThread
Kurze Frage zwischendurch:
Sind Zugriffe (schreibend/lesend) auf Boolean-Variablen atomar bzw. threadsicher? D.h. kann ich auf eine Boolesche Variable einer von TThread abgeleiteten Klasse vom VCL-Hauptthread aus ohne Synchronisation (z.B. per InterlockedExchange) (schreibend) darauf zugreifen, wenn die auch in der Execute-Methode abgefragt und/oder gesetzt wird?
Hab hier einen Code, der das macht, und der auch ganz gut läuft, aber das heißt ja nichts. :dunce:
BenBE - Do 02.07.09 10:50
Zugriffe auf einzelne Bytes sind dann atomar, wenn die ausführende Schreiboperation atomar ist.
Ein a+=2; wäre also nicht atomar (Read-->Modify-->Write), während ein Inc (CPU-Befehl dafür) durchaus atomar ist.
Was ggf. noch beachtet werden muss, ist ob du mehrere Schreiber und einen Leser oder einen Schreiber und mehrere Leser hast.
Gausi - Do 02.07.09 10:58
Bei Inc() gibt es afaik durchaus Probleme. Ich hab da etwas dunkel was aus den vorletzten Delphitagen in Erinnerung. Da kommt es bei parallelen Incs / Decs aufgrund von Caching-Effekten bei Mehrkernprozessoren zu sehr unschönen Effekten (10000 mal inc und 10000 mal dec in zwei parallel laufenden Threads ergibt am Ende nicht Null oder sowas). Ok, das war bei Integer, nicht bei Bytes.
Ich habe zwei Threads, VCL- und Sekundär-Thread. Beide haben Schreib- und Lesezugriff auf die Variable. Zugriffe sind in der Form myVar := True oder myVar := False, aber nicht myVar := Not myVar.
jaenicke - Do 02.07.09 10:59
Gausi hat folgendes geschrieben : |
| ohne Synchronisation (z.B. per InterlockedExchange) (schreibend) darauf zugreifen |
InterlockedExchange macht das ja gerade atomar. Das heißt in dem Fall braucht man auch keine Synchronisation, vorausgesetzt es werden nur die InterlockedXYZ Operationen darauf ausgeführt.
(Wie das bei anderen Zugriffen aussieht, weiß ich gerade gar nicht, habe ich nie versucht. :gruebel:)
Gausi - Do 02.07.09 11:02
@
jaenicke: Das war wohl misverständlich ausgedrückt. InterlockedExchange macht das atomar, das weiß ich, und nutze es z.B. bei Integer-Variablen. Dafür braucht man dann aber jeweils einen Setter und Getter - die Frage ist also, ob das bei Boolean ohne geht. ;-)
delfiphan - Mo 24.08.09 21:59
32-bit Lese- und Schreiboperationen sind atomar, wenn die Adresse 32-bit aligned ist. Das gilt analog auch für 16-bit und 8-bit. Wenn das Boolean also packed ist und der entsprechende 8-bit Befehl in Assembler verwendet wird, müsste es eigentlich immer klappen.
Mit atomar ist hier gemeint, dass der Fall nicht eintritt, dass erst eine Hälfte einer 32-bit Variablen geschrieben ist, wenn du davon liest.
Was aber nicht garantiert ist, ist der Zeitpunkt, wann die Leseoperation stattfindet. Es ist durchaus möglich, dass der CPU deine Befehle etwas umordnet (-> ansonsten Memory barrier verwenden). Deswegen musst du etwas aufpassen, wenn du einen eigenen Spinlock oder so schreibst.
Inc ist nicht atomar. Da musst du (in Assembler) lock inc nehmen. Die ist aber natürlich etwas langsamer.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| var I: Integer; begin asm lock inc I; end; end; |
Oder die entsprechende InterlockedIncrement Funktion von der WinAPI.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!