Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Threads: Wie globale Int64-Variable sicher inkrementieren? (https://www.delphipraxis.net/27092-threads-wie-globale-int64-variable-sicher-inkrementieren.html)

Dani 4. Aug 2004 01:39


Threads: Wie globale Int64-Variable sicher inkrementieren?
 
Hi,

Ein Beispiel: In Unit1.pas ist die globale Variable TotalBytesRec definiert.
Delphi-Quellcode:
var
 TotalBytesRec : Int64 = 0;
In einem von mehreren Threads wird folgender Code ausgeführt:

Delphi-Quellcode:
procedure TDownloadThread.OnWork(Sender: TObject; AWorkMode: TWorkMode;
  const AWorkCount: Integer);
var i: Integer;
begin
 If AWorkMode=wmRead then
  begin
   Inc(TotalBytesRec, AWorkCount-FLastWorkCount);
   i := PercentDone;
   PercentDone := trunc((AWorkCount / FileSize) * 100);
   If i<>PercentDone then Synchronize(UpdateProgress);
   FLastWorkCount := AWorkCount;
  end;
end;
Das Problem:
Der Aufruf von Inc() macht mir Sorgen; ist das überhaupt Thread-sicher? Bei nem Int64 wird wohl kaum eine atomare Operation daraus :?

Gruß,
Dani

supermuckl 4. Aug 2004 01:58

Re: Threads: Wie globale Int64-Variable sicher inkrementiere
 
sichere das mit critical section ab

oncreate(form1):
sect := Tcriticalsection.create;


sect.enter;
inc(bla);
sect.leave;


onclose(form1):
sect.free;

Robert Marquardt 4. Aug 2004 05:39

Re: Threads: Wie globale Int64-Variable sicher inkrementiere
 
Beschaeftige dich mal mit "threadvar" (siehe Delphi-Hilfe).

Dani 4. Aug 2004 15:47

Re: Threads: Wie globale Int64-Variable sicher inkrementiere
 
In diesem Thread schreibt Luckie:

Zitat:

Zitat von Luckie
Zitat:
BeginThread setzt die globale Variable IsMultiThread auf True und macht so Zugriffe auf den Heap so threadsafe

Zitat:

Zitat von Luckie
Der Heap ist ein Speicherbereich im Adressraum des Prozesses, wie der Stack auch, nur dass er etwas anders organisiert ist. Wenn ich jetzt eine multithread Anwendung habe und ein Thread schreibt etwas in den Heap und ein anderer Thread liest gerade zufälligerweise an der gleichen Adresse, kann es passieren, dass der lesende Thread die Daten in einem inkonsistenten Zustand vor findet. Threadsafe bedeutet hier, dass jegliche Zugriffe auf den Heap atomare Operationen sind. Das heißt, wenn ein Thread auf den Heap zugreift, ist er für andere gesperrt.

Zitat:

Zitat von Chewie
Welche Daten sind denn im Heap abgelegt?

Zitat:

Zitat von Luckie
Globale Variablen zum Beispiel

Wenn das stimmt, dann ist jeder Zugriff eines TThread-Nachfahren auf globale Variablen ohne weiteres Zutun threadsafe. :party:

Wegen der threadvars: Wenn ich die Variablen so deklariere:

Delphi-Quellcode:
threadvar
  TotalBytesRec : Int64;
  LastTotalBytesRec : Int64;
dann bleibt jeder Schreibzugriff aus den Threads heraus wirkungslos. Ich muss da irgendwas falsch verstanden haben.

Gruß,
Dani

sakura 4. Aug 2004 15:50

Re: Threads: Wie globale Int64-Variable sicher inkrementiere
 
Zitat:

Zitat von Dani
Wenn das stimmt, dann ist jeder Zugriff eines TThread-Nachfahren auf globale Variablen ohne weiteres Zutun threadsafe. :party:

Nicht unbedingt. Wenn ich eine Variable zwischenspeichere, ändere und wieder zurück schreibe gibt es zwar keine Probleme mit dem eigentlichen Zugriff auf den Speicher, allerdings uU mit der Gültigkeit des Wertes.

INC hingegen ist auf Einprozessor-Systemen Thread-Sicher, auf Mehrprozessor-Systemen ist das jedoch nicht garantiert, da muss dann unbedingt mit einer CriticalSection u.ä. gearbeitet werden.

...:cat:...

himitsu 3. Mär 2012 14:30

AW: Threads: Wie globale Int64-Variable sicher inkrementieren?
 
Nur weil ich's grade seh, auch wenn's etwas alt ist. Aber bevor es nochjemand findet...

Zitat:

da muss dann unbedingt mit einer CriticalSection u.ä. gearbeitet werden.
MSDN-Library durchsuchenInterlockedIncrement64

Unter Assembler kann man dieses auch benutzen, wenn sich diese Operation als ein Befehl ausführen läßt. (z.B. auf eimer 64 Bit-CPU oder mit MMX)
Delphi-Quellcode:
asm
  LOCK INC RAX
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:25 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