![]() |
AW: TInterlocked.Exchange bei Zugriff eines nur lesenden Threads?
Zitat:
|
AW: TInterlocked.Exchange bei Zugriff eines nur lesenden Threads?
Zitat:
|
AW: TInterlocked.Exchange bei Zugriff eines nur lesenden Threads?
Das ist eine Frage der Ausrichtung...
Wenn Du mit {$A1} arbeitest ist es nicht sicher... Wie ich gelesen haben übrigens auch nicht zu 100% bei einem Interger. Also lieber ein Interlock oder CS Mavarik |
AW: TInterlocked.Exchange bei Zugriff eines nur lesenden Threads?
Zitat:
Es ist in 99% der Fälle besser die entsprechenden Bibliotheksfunktionen und Datentypen (richtig ausgerichtet) für atomare Zugriffe zu benutzen. Und es nicht nur der Speicher selbst, auch der Compiler und Out-Of-Order-Execution kann dir reinpfuschen:
Delphi-Quellcode:
// Thread 1
ptr = Class.create(): ptr.value = 1337; global_ptr = ptr;
Delphi-Quellcode:
Der Compiler weiß nicht, dass global_ptr von mehreren Threads benutzt wird und ordnet das wegen Optimierung so um (oder der Prozessor macht das; warum auch nicht):
// Thread 2
write(global_ptr.foo); // 1337?
Delphi-Quellcode:
Den Fehler finde erst mal :mrgreen:
// Thread 1
ptr = Class.create(): global_ptr = ptr; ptr.value = 1337; Die Bibliotheksfunktionen sind entweder dem Compiler bekannt oder zumindest undurchsichtig, so dass er solche Spielchen lässt. Intern wird da sichergestellt, dass der Prozessor nichts umordnet (Memory Barriers oder andere Tricks). Wenn es nur um Sachen geht, die schiefgehen können (z.B. Integer für Fortschrittsanzeige auslesen) mag das alles gut gehen. Alles darüber hinaus sollte man vorsichtig angehen. |
AW: TInterlocked.Exchange bei Zugriff eines nur lesenden Threads?
Verdammt, dann habe ich wohl etwas Arbeit vor mir :?
Wie gehe ich am besten bei Enumtypen vor? Alles mit $Z4 deklarieren und dann immer die Integer Variante von InterlockedExchange benutzen dürfte die sicherste Methode sein oder? Gibt es analog hierzu auch eine Möglichkeit "ranged types" auf eine bestimmte Größe zu forcen?
Delphi-Quellcode:
type
TRangedType = 0..1023; |
AW: TInterlocked.Exchange bei Zugriff eines nur lesenden Threads?
Zitat:
Delphi-Quellcode:
TFoo = class
private FCS : TCriticalSection; FValue : string; function GetValue : string; procedure SetValue(const Value : string) : string; public constructor Create; destructor Destroy; override; property Value : string read GetValue write SetValue; end; constructor TFoo.Create; begin inherited; FCS := TCriticalSection.Create; end; destructor TFoo.Destroy; begin FreeAndNil( FCS ); inherited; end; function GetValue : string; begin FCS.Enter; try Result := FValue; finally FCS.Leave; end; end; procedure SetValue(const Value : string) : string; begin FCS.Enter; try FValue := Value; finally FCS.Leave; end; end; |
AW: TInterlocked.Exchange bei Zugriff eines nur lesenden Threads?
Klar, das ist sicherlich ein brauchbarer Ansatz (den ich auch partiell schon implementiert hatte). Allerdings habe ich gelesen, dass Critical Sections nicht umbedingt super performant sind. Zumindest bei den Werten, die alle paar Milisekunden aktualisiert werden, wollte ich lieber die Interlocked Funktionen verwenden.
Kann man bezüglich der "ranged types" was machen, oder bin ich hier gezwungen Critical Sections zu benutzen? |
AW: TInterlocked.Exchange bei Zugriff eines nur lesenden Threads?
Zitat:
Delphi-Quellcode:
, oder, oder, oder, oder, ..... )
TMonitor
Welchen, das hängt eben davon ab, was da atomar ablaufen soll/muss. Ein
Delphi-Quellcode:
geht eben nur für einen Wert und eben nur für bestimmte Typen
TInterlocked
![]() |
AW: TInterlocked.Exchange bei Zugriff eines nur lesenden Threads?
Und die Synchronisationsobjekte (unter System.SyncObjs) leiten sich doch alle von einer gemeinsamen Oberklasse ab. Wenn du später eine die TCriticalSection gegen etwas anderes austauschen willst, ist das nur eine Sache- Ich hätte Sir Rufos Ansatz noch um eine Typdefinition erweitert:
Delphi-Quellcode:
Dann kannst du später alles in einer Zeile austauschen.
TFoo = class
protected type TSyncObj = TCriticalSection; private FCS : TSyncObj; FValue : string; function GetValue : string; procedure SetValue(const Value : string) : string; public constructor Create; destructor Destroy; override; property Value : string read GetValue write SetValue; end; |
AW: TInterlocked.Exchange bei Zugriff eines nur lesenden Threads?
Zitat:
Bin momentan am sichten, auf welche Felder in welcher Form von wo aus zugegriffen wird. Momentan habe ich vier verschiedene Modi:
Hoffe ich habe da grade keine Logikfehler eingebaut. Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:39 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz