Autor Beitrag
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 481

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Do 02.07.09 10:44 
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:

_________________
We are, we were and will not be.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: 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.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Gausi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 481

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: 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.

_________________
We are, we were and will not be.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 02.07.09 10:59 
user profile iconGausi hat folgendes geschrieben Zum zitierten Posting springen:
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 481

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Do 02.07.09 11:02 
@user profile iconjaenicke: 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. ;-)

_________________
We are, we were and will not be.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: 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.
ausblenden 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.