Einzelnen Beitrag anzeigen

Benutzerbild von Sir Rufo
Sir Rufo

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

AW: TCriticalSection: Einmal global oder immer lokal erstellen?

  Alt 26. Nov 2011, 00:23
CriticalSections müssten schon global sein, weil alle Thread sie ja kennen müssen.
Nein, müssen schon mal gar nicht. Und was interessiert es den Thread A wenn in Thread B Daten geändert werden. Möglich ja, aber warum sollte man sich eine Blockade für alle Threads bauen?
Ich dachte immer, die sollen so schnell als möglich ihren Job machen und da ist das Ausbremsen doch völlig kontraproduktiv.
Zitat von Oberlehrer:
Eine CriticalSection muss in dem Kontext vorhanden sein, in dem auch die Daten liegen, die durch die CriticalSection geschützt werden sollen.

Bei einer globalen Variable muss man eine globale CriticalSection haben, aber wer benutzt schon globale Variablen.

Um den Datenzugriff zu schützen reicht es nicht nur den Schreibzugriff abzusichern, sondern auch den Lesezugriff!
Denn was soll denn zurückgeliefert werden, wenn während des Lesens von einem anderen Thread der Wert geändert wird? Die Hälfte vom alten und die Hälfte vom neuen Wert?

Hier mal das Beispiel für eine Klasse mit einer geschützten Eigenschaft.
(Das Erzeugen und Zerstören der CS lasse ich mal weg)

FALSCH:
Delphi-Quellcode:
TMyClass = class
strict private
  _CS : TCriticalSection;
private
  fMyValue : string;
  procedure SetMyValue( const Value : string );
public
  property MyValue : string read fMyValue write SetMyValue;
end;

procedure TMyClass.SetMyValue( const Value : string );
begin
  _CS.Enter;
  try
    fMyValue := Value; // geschützter Schreib-Zugriff
  finally
    _CS.Leave;
  end;
end;
RICHTIG:
Delphi-Quellcode:
TMyClass = class
strict private
  _CS : TCriticalSection;
private
  fMyValue : string;
  function GetMyValue : string;
  procedure SetMyValue( const Value : string );
public
  property MyValue : string read GetMyValue write SetMyValue;
end;

function TMyClass.GetMyValue : string;
begin
  _CS.Enter;
  try
    Result := fMyValue; // geschützter Lese-Zugriff
  finally
    _CS.Leave;
  end;
end;

// Schreibzugriff geschützt

procedure TMyClass.SetMyValue( const Value : string );
begin
  _CS.Enter;
  try
    fMyValue := Value; // geschützter Schreib-Zugriff
  finally
    _CS.Leave;
  end;
end;
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)
  Mit Zitat antworten Zitat