Einzelnen Beitrag anzeigen

Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: Änderungen von Variablen synchronisieren

  Alt 17. Mär 2012, 21:01
Eigentlich ist das mit der TCriticalSection sehr einfach.

Stell dir eine Kreuzung vor. Die beiden Straßen sind einmal der MainThread und der Thread den du laufen lässt. Die CriticalSection ist nun die Ampel, die dafür sorgt, dass über den Kreuzungspunkt (Zugriff auf die Variable) immer nur eine Fahrbahn (Thread) freigegeben ist.

Delphi-Quellcode:
TMyThread = class( TThread )
strict private
  FCS : TCriticalSection;
private
  FIntStr : string;
  procedure SetIntStr( const Value : string );
  function GetIntStr : string;
protected
  procedure Execute; override;
public
  property IntStr : string read GetIntStr write SetIntStr;
end;

...

procedure SetIntStr( const Value : string );
begin
  FCS.Enter; // Betreten der CS
  try
    FIntStr := Value;
  finally
    FCS.Leave; // Verlassen der CS
  end;
end;

function GetIntStr : string;
begin
  FCS.Enter; // Betreten der CS
  try
    Result := FIntStr;
  finally
    FCS.Leave; // Verlassen der CS
  end;
end;
Bei FCS.Enter wird solange gewartet, bis die CriticalSection frei ist und dann betreten.
Innerhalb eines Thread-Kontexts darf die CS sooft betreten werden, wie man möchte. Die CS sperrt ja nur gegen Zugriffe durch unterschiedliche Thread-Kontexte.

Die Getter und Setter der Eigenschaft kümmern sich nun darum, dass der Zugriff geregelt wird, egal aus welchem Thread-Kontext man darauf zugreift.
Aber ... innerhalb des Threads könnte man ja direkt auf FIntStr zugreifen, aber dieser Zugriff ist nicht abgesicht (über die CS), also sollte der Zugriff auch innerhalb des Threads über die Eigenschaft und nicht über das Feld erfolgen.
Delphi-Quellcode:
procedure TMyThread.Execute;
begin
  while not Terminated do
  begin
    ...
    // FIntStr := 'So nicht';
    IntStr := 'So geht das';
    ...
  end;
end;
end;
Der Vollständigkeit halber sei noch erwähnt, dass die Instanz von FCS natürlich von TMyThread im Constructor erzeugt und im Destructor wieder freigegeben werden sollte bzw. muss.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (17. Mär 2012 um 21:05 Uhr)
  Mit Zitat antworten Zitat