Einzelnen Beitrag anzeigen

Benutzerbild von geskill
geskill

Registriert seit: 17. Feb 2007
Ort: NRW
420 Beiträge
 
Delphi 2010 Professional
 
#5

AW: Kurze Frage zur Thread Sicherheit

  Alt 4. Okt 2012, 11:04
Hallo luke2,
du kannst dafür am besten einen MREW benutzen. Damit können mehrere Threads gleichzeitig lesend drauf zugreifen, aber immer nur einer schreibend. Natürlich müssen beide Threads die gleiche Instanz von dem TSafeArray bekommen

Bei so kritischen Sachen würde ich nie wie du vorhast die Array Instanz einem Thread direkt mitteilen.

Dies ist eine vereinfachtere Variante die ich gerade im Einsatz habe:
Das ist an sich eigentlich schon ziemlich performant, aber du könntest jetzt ein lokales Array/Liste etc. anlegen, die alle Lesezugriffe auf die versch. Indexe speichert. Und beim Schreiben wird dann geprüft ob dieser Index in der Liste ist, wenn ja muss dort beim zugreifen eben gewartet werden. Aber ich würde das mit dem gleichzeitigen auf ein Index auch sein lassen und immer als schreibend behandeln.
Delphi-Quellcode:
uses
  // Delphi
  Math,
  // OmniThreadLibrary
  OtlSync;

type
  TSafeArray = class
  private
    FArray: array of Integer;
    FLock: TOmniMREW;
  public
    constructor Create;

    procedure SetResult(AIndex: Integer; const AValue: Integer);
    function GetResult(AIndex: Integer): Integer;
  end;

constructor TSafeArray.Create;
begin
  SetLength(FArray, 0);
end;

procedure TSafeArray.SetResult(AIndex: Integer; const AValue: Integer);
begin
  FLock.EnterWriteLock;
  try
    SetLength(FArray, Max(AIndex, length(FArray)) + 1); // Lesezugriff: length(); Schreibzugriff!: SetLength()
    FArray[AIndex] := AValue; // Schreibzugriff: FArray[Index]
  finally
    FLock.ExitWriteLock;
  end;
end;

function TSafeArray.GetResult(AIndex: Integer): Integer;
var
  Index: Integer;
begin
  Result := -1;

  Index := AIndex;

  FLock.EnterReadLock; // starte das lesen
  try
    if Index < length(FArray) then // Lesezugriff: length()
      Result := FArray[Index]; // Lesezugriff: FArray[Index]
  finally
    FLock.ExitReadLock; // beende das lesen
  end;
end;
Grüße
Sebastian

Geändert von geskill ( 4. Okt 2012 um 11:12 Uhr)
  Mit Zitat antworten Zitat