Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Threads: Wieso gibt's keine InterlockedRead - Funktion? (https://www.delphipraxis.net/23308-threads-wieso-gibts-keine-interlockedread-funktion.html)

TStringlist 1. Jun 2004 11:35


Threads: Wieso gibt's keine InterlockedRead - Funktion?
 
Hallo,

bei einem kleinen Trip durchs Thema 'Threads' bin ich gerade bei den Interlocked-Funktionen angekommen ...und hätte da jetzt mal folgende kurze Frage: Warum gibt es hier eigentlich keine derartige Funktion mit der man eine von mehreren Threads gleichzeitig genutzte Variable einfach nur Auslesen kann, ...also ohne sie auch jedesmal immer mit verändern zu müssen.

Es fällt nämlich auf, dass diese Interlocked-Funktionen den Wert der jeweiligen Variablen immer auch mit verändern. ...Was vielleicht auch wiederum heißen könnte, dass für das nur Lesen einer solchen Variablen deswegen eigentlich auch gar keine Interlocked-Funktion notwendig ist? ...und zwar deswegen, weil ein Thread fürs Schreiben einer Variablen bis zum Schreibende dann jeweils ununterbrochen durcharbeiten darf und somit eh immer gefahrlos gelesen werden kann?


Weiß hier irgendjemand eventuell genaueres?

Thx im Voraus


PS. Denkbare Situationen in denen das nützlich wäre, gibt's ja auch genug, ...z.B. solche, in denen ein quasi 'WatchDog'-Thread die Arbeit anderer Threads überwacht, und zwar eben durch das nur Auslesen (ohne Änderung!) von z.B. kontinuierlich anwachsenden Variablewerte mit denen diese anderen Threads dann auch normal weiterzuarbeiten hätten...

PPS. Jetzt mal InterlockedCompareExchange ausgenommen, mit der man sich ja so eine Abfrage (ohne gleichzeitig Änderung der abzufragenden Variablen) auch zur Not noch selbst herbeikonstruieren könnte, die dafür aber bestimmt nicht gedacht ist, oder?

Meflin 1. Jun 2004 11:47

Re: Threads: Wieso gibt's keine InterlockedRead - Funktion?
 
ganz einfach: beim auslesen entstehen keinerlei komplikationen, d.h. zum auslesen muss der speicher nicht zwischengesperrt werden, da beliebeig viele threads gleichzeitig lesen können dürfen.

TStringlist 1. Jun 2004 12:52

Re: Threads: Wieso gibt's keine InterlockedRead - Funktion?
 
@Melfin

ich fragte nur, weil für ein nur Lesen im SpinLock-Tutorial extra nochmal die InterlockedExchanged-Funktion benutzt wurde, ...mir selbst diesbezüglich allerdings auch nicht absolut sicher war, ob es aber andrerseits dann ganz ohne Interlocked auch tatsächlich geht (...was sich einem dann aber aus den besagten Gründen wieder irgendwie aufdrängt).

Du glaubst also auch, dass ein nur Auslesen keine solche Funktionen benötigt. Hmmm, dachte ich mir's also *g*. Thx.

Meflin 1. Jun 2004 12:54

Re: Threads: Wieso gibt's keine InterlockedRead - Funktion?
 
ich glaube es nicht nur, ich weis es sogar ;-) wie schon gesagt muss man einen lesevorgang ja nicht absichern!

TStringlist 1. Jun 2004 13:22

Re: Threads: Wieso gibt's keine InterlockedRead - Funktion?
 
ah, supi.

Thx^2

woki 1. Jun 2004 13:28

Re: Threads: Wieso gibt's keine InterlockedRead - Funktion?
 
Dann vielleicht doch:

Auch Lesevorgänge muß man absichern, wenn diese nicht atomar sind, d.h. während ein Thread am Lesen ist, kann ja ein anderer, der schreiben will, die Kontrolle bekommen, und dann bekommt der lesende bei einem nichtatomaren Lesevorgang eventuell nicht konsistente Daten.

Grüsse
Woki

Meflin 1. Jun 2004 14:15

Re: Threads: Wieso gibt's keine InterlockedRead - Funktion?
 
nein, weil der, der schreiben will, normalerweise keinen zugriff bekommt, weil ja ein thread am lesen ist

TStringlist 1. Jun 2004 16:22

Re: Threads: Wieso gibt's keine InterlockedRead - Funktion?
 
@Meflin

woher weiß aber der Thread (der der jetzt schreiben möchte), dass ein anderer gerade liest, wenn dieser andere das wiederum nicht durch das Benutzen irgendeiner dieser speziellen Funktionen (oder sonst irgendwie) bekannt gemacht hat?

@woki

...und wann ist ein Lesevorgang atomar?

In meinem Fall ging ich bei der so 'WatchDog-Thread'-mäßig jeweils zu prüfende Variablen von einer einfache Integergröße aus. Wäre das noch ein atomarer Lesevorgang? Wann ist ein solcher Lesevorgang atomar? Wenn er sich in nur einen einzigen (in solchen Fällen immer benutzten) Assembler-Befehl übersetzen lässt?

Beim Lesen komplexer (also nicht-atomarer?) Daten, wie z.B. Records o.ä., ist das schon eher nachvollziehbar. Aber die könnte man ja mit so einer Interlocked-Funktion auch ebenfalls nicht schreiben. Dafür bräuchte man, ob fürs Lesen oder Schreiben, sowieso eher eine Critical Section?

@Alle

Könnte man sagen: Für alle Variablen, die ich über die Interlocked-Funktionen verändern kann (wenn ich das wollen würde), brauche ich, wenn ich die jetzt aber einfach nur auslesen möchte, keine Absicherung? ...weil ein Lesen in diesen Fällen event. immer atomar wäre?

Ratte 1. Jun 2004 18:53

Re: Threads: Wieso gibt's keine InterlockedRead - Funktion?
 
Hi,

bei mir hagelt's Fehler wenn zwei gliechzeitig auf eine Variable zugreifen.

Ratte

TStringlist 1. Jun 2004 20:29

Re: Threads: Wieso gibt's keine InterlockedRead - Funktion?
 
aber nicht, wenn beide Threads nur lesend zugreifen, oder? Dann dürfte ja ohnehin kein Fehler eintreten, egal ob ein solcher Lesevorgang jetzt in einem einzigen (atomaren) Arbeitsakt ausgeführt würde oder dieser durch einen event. zweiten Lesevorgang eines anderen Threads unterbrochen werden kann ...weil ja die Variable auch durch diesen zweiten Lesevorgang unverändert bliebe und damit auch das erste Auslesen danach noch ohne Schwierigkeiten bzw. ohne Fehler beendet werden könnte.

Ein Problem bei einem Lesevorgang durch einen Thread1 habe ich doch nur dann, wenn ein solcher quasi irgendwo in der Mitte durch einen anderen Thread2, der nun gerade auf die gleiche Variable schreiben will, unterbrochen werden kann und der damit einen Teil der von Thread1 danach noch fertig zu lesenden Variablen ändert ...was ja bei Thread1 dann schließlich meistens einen falschen End-Wert ergeben dürfte.

Und daher auch nochmal die Frage: Sind Nur-Lesevorgänge bezüglich der Variablen, die sonst über diese Interlocked-Funktionen auch immer mit verändert werden, ...sind die überhaupt unterbrechbar, also nicht atomar? Und wenn ja, warum gibt es dann eigentlich keine InterlockedRead-Funktion. Das wäre doch dann quasi nur das aller logischste überhaupt, oder?

Motzi 1. Jun 2004 22:59

Re: Threads: Wieso gibt's keine InterlockedRead - Funktion?
 
Also Jeffrey Richter schreibt:
Zitat:

Zitat von Jeffrey Richter
Es gibt keine Interlocked-Funktion, die einfach nur einen Wert liest (ohne ihn zu ändern). da eine solche Funktion nicht nötig ist. Wenn ein Thread nur versucht, den Inhalt einer Variablen zu lesen, deren Wert nur mithilfe von Interlocked-Funktionen geändert wird, handelt es sich immer um einen brauchbaren Wert. Zwar wissen Sie nicht, ob Sie den ursprünglichen oder den geänderten Wert lesen, aber Sie wissen zumindest, dass es einer von beiden ist. Das genügt für die meisten Anwendungen.


TStringlist 2. Jun 2004 01:39

Re: Threads: Wieso gibt's keine InterlockedRead - Funktion?
 
Zitat:

... Zwar wissen Sie nicht, ob Sie den ursprünglichen oder den geänderten Wert lesen, aber Sie wissen zumindest, dass es einer von beiden ist...
Also das interpretiere ich dann mal so, dass ein solches Read dann zwar auch vom Ändern eines anderen Threads unterbrochen werden kann, aber eben nicht so, dass der eigentliche Variable-Wert dabei quasi in der Mitte zersäbelt würde. Der danach gelesene Variablewert ist dann entweder derjenige vor dem Zugriff des schreibenden Threads oder der, der sich nach dem Schreibzugriff erst ergeben hat... ---> und das ist ja nunmal auch eigentlich immer der normale Umstand mit dem sich solche quasi 'WatchDog'-Threads sowieso abgeben müssen (also entweder mit einem alten oder einem neuen Variablen- bzw. Flag-Wert etc.). Im Zweifelsfall müsste so ein Thread hier dann eben nur noch einen Schleifenumlauf mehr machen, um diesen neuen Wert dann endlich auch noch registriert zu haben ...und reagiert dann. In allen nicht-zeitkritischen Abläufen wäre das natürlich immer ok.

Thx, dieses brauchbare Info passte gut rein :thuimb:

NicoDE 2. Jun 2004 07:44

Re: Threads: Wieso gibt's keine InterlockedRead - Funktion?
 
Ein Problem bekommt man nur, wenn man vergisst, dass die unterschiedlichen Prozessoren (ohne InterLocked) unterschiedliche Ansichten des Arbeitspeichers haben können (durch asynchrone Caches).

Beispiel aus dem PSDK...
Delphi-Quellcode:
var
  Value: Integer;
  ValueHasBeenComputed: LongBool = False;

procedure CacheComputedValue;
begin
  if not ValueHasBeenComputed then
  begin
    Value := ComputeValue();
    ValueHasBeenComputed := True;
  end;
end;

function FetchComputedValue(out Val: Integer): LongBool;
begin
  if ValueHasBeenComputed then
  begin
    Val := Value;
    Result := True;
  end
  else
    Result := False;
end;
Das Problem ist hier... ein Thread der gerade CacheComputedValue aufruft und ValueHasBeenComputed setzt und mit den anderen Prozessoren synchronisiert hat, muss nicht zwingend den neuen Wert von Value in die gemeinsame Speicheransicht übertragen haben (auch wenn die Befehle hintereinander stehen!). Ein zweiter Thread (auf einem anderen Prozessor) könnte also ValueHasBeenComputed = True 'sehen' aber noch nicht den neuen Wert von Value.

Erst durch die Interlocked/Wait/CriticalSection/Synchronisations-Funktionen werden die Caches der Prozessoren synchronisiert.
Delphi-Quellcode:
procedure CacheComputedValue;
begin
  if not ValueHasBeenComputed then
  begin
    Value := ComputeValue();
    InterlockedExchange(ValueHasBeenComputed, True);
  end;
end;
Ergo: Lesen ohne Probleme, Setzen mit Interlocked.

ps: welche Operationen 'atomar' sind und welche nicht, steht in den jeweiligen Prozessor-Beschreibungen... grobe Richtlinie: Integer-Operationen die nur eine Prozessoranweisung benötigen.

TStringlist 2. Jun 2004 13:05

Re: Threads: Wieso gibt's keine InterlockedRead - Funktion?
 
Zitat:

Ergo: Lesen ohne Probleme, Setzen mit Interlocked.
Danke fürs nochmalige Bestätigen, und zwar auch für diesbezüglich etwas komplexere bzw. empfindlichere Konstruktionen wie Multiprozessor-PCs (wenn ich das richtig verstanden habe).

funkymick 3. Jun 2004 09:28

Re: Threads: Wieso gibt's keine InterlockedRead - Funktion?
 
ich arbeite auch im moment an einer multithreading-anwendung und muss aus mehreren threads variablen lesen bzw. schreiben... da hats bei mir auch oft genug exceptions gehagelt :gruebel:

dann habe ich von den CriticalSections zur absicherung von solchen lese/schreibvorgängen gelesen...

und unter delphi gibt es die klasse TMultiReadExclusiveWriteSynchronizer...

ein einfaches

T:=TMultiReadExclusiveWriteSynchronizer.Create;

erstellt das objekt und mit

T.BeginWrite;
bzw.
T.EndWrite;
kann ein schreibvorgang abgesichert werden... sprich solange nicht T.EndWrite; aufgerufen wurde, haben andere threads keinen lese-zugriff und warten bis endWrite aufgerufen wurde...

Voraussetzung ist, dass Lesevorgänge dann auch mit T.BeginRead; und T.EndRead; umgeben sind...

T.BeginWrite;
Variable1:=Wert;
T.EndWrite;

T.BeginRead;
Variable2:=Variable1;
T.EndRead;

Lesen funktioniert gleichteitig schreiben nur exclusiv...

Vielleicht Bringts dem einen oder anderen was...

woki 6. Jun 2004 16:20

Re: Threads: Wieso gibt's keine InterlockedRead - Funktion?
 
Zitat:

Zitat von Meflin
nein, weil der, der schreiben will, normalerweise keinen zugriff bekommt, weil ja ein thread am lesen ist

Nein. Das Lesen einer Integervariablen ist atomar, das eines Paares von zwei aufeinanderfolgenden Integern schon nicht mehr, das heißt Thread 1 liest integer 1, verliert dann die Kontrolle, Thread 2 schreibt ein neues Paar, Thread 1 liest Wert 2 und schon hat Thread 1 inkonsistente Werte, nicht technisch aber doch fachlich.

Grüße
Woki

Meflin 6. Jun 2004 16:43

Re: Threads: Wieso gibt's keine InterlockedRead - Funktion?
 
aja.
1) was is los?
2) was hat das mit meiner aussage zu tun?

woki 6. Jun 2004 17:38

Re: Threads: Wieso gibt's keine InterlockedRead - Funktion?
 
Zitat:

Zitat von Meflin
aja.
1) was is los?
2) was hat das mit meiner aussage zu tun?

es hat etwas mit deinem nein auf meine letzte Aussage zu tun, weil das nein falsch ist.
Außerdem ist die Tatsache, daß ein Thread im Rahmen seiner Arbeit daten liest, überhaupt kein Grund für den scheduler ihm nicht die Kontrolle zu entziehen.


Grüsse
Woki

supermuckl 6. Jun 2004 18:08

Re: Threads: Wieso gibt's keine InterlockedRead - Funktion?
 
also ich hab auch schon bisschen erfahrung mit den threads.. besonderst krass is ja die thread verwaltung und synchronisation
bei internet anwendungen ( z.b. multithreaded server portchecker ). Da hab ich mir immer einen thread gebastelt der sich die "jobs" aus einer für ihn zugewiesenen klasseninstanz ( index einer liste ) rausholt, die abarbeitet und dann die results wieder in seine instanzen schreibt.. diese lese/schreibzugriffe hab ich natürlich auch mit EnterCriticalSection(section); und Leave umklammern müssen...

was mich auch viel nerven gekostet hat ist die tatsache das wenn ich in einem thread globale variablen deklariert hab ( sieht ja so aus als ob die eigentlich nur in dem thread aktiv sein sollten ) oder sogar public oben in die thread classe geschrieben hab.. das das alle threads zubgriff drauf haben.. naja hab ichs halt in die private section rein geschoben und dann hatte jeder thread seine eigenen variablen die kein anderer veränderte o_O

schon hart mit den dingern.. aber wenns mal rennt dann rennts krass :D :coder:


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:58 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz