AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Kurze Frage zur Thread Sicherheit

Ein Thema von luke2 · begonnen am 4. Okt 2012 · letzter Beitrag vom 5. Okt 2012
Antwort Antwort
luke2

Registriert seit: 17. Jun 2009
117 Beiträge
 
#1

Kurze Frage zur Thread Sicherheit

  Alt 4. Okt 2012, 00:50
Delphi-Version: XE2
Hi, ist es sicher, wenn ein Thread lesend und schreibend auf ein Index eines Array zugreift und ein anderer Thread lesend und schreibend auf das gleiche Array mit einem anderen Index zugreift? Oder müssen alle Zugriffe synchronisiert werden?
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#2

AW: Kurze Frage zur Thread Sicherheit

  Alt 4. Okt 2012, 01:26
Sollte theoretisch sicher sein, solange wirklich immer nur ein Thread auf einen Index gleichzeitig zugreift.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
luke2

Registriert seit: 17. Jun 2009
117 Beiträge
 
#3

AW: Kurze Frage zur Thread Sicherheit

  Alt 4. Okt 2012, 02:04
OK, danke für die Antwort.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.338 Beiträge
 
Delphi 12 Athens
 
#4

AW: Kurze Frage zur Thread Sicherheit

  Alt 4. Okt 2012, 08:24
Und sich das Array selber nicht verändert, also kein SetLength und Co.

Was ist das denn für ein Array?
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
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
luke2

Registriert seit: 17. Jun 2009
117 Beiträge
 
#6

AW: Kurze Frage zur Thread Sicherheit

  Alt 4. Okt 2012, 15:31
Danke, das sieht gut aus, geskill, aber ich möchte eigentlich keine externen Komponenten benutzen.

Es sieht ungefähr so aus:
Delphi-Quellcode:
type
  T = record
    Str: string;
    Use: Boolean;
  end;

private
  A: Array[0..5] of T;

procedure TThread.Add(const S: string);
begin
  with A[GetFreeField] do
  begin
    Str := S;
    Use := True;
  end;
end;

procedure TThread.Execute;
begin
  while not Terminated do
  begin
    for I := Low(A) to High(A) do
      if Use then
      begin
        //hier werden nur Felder von A[I] gelesen und geändert
      end;
    Sleep(1);
  end;
end;
Add wird aus dem Hauptthread aufgerufen. Use ist natürlich anfangs immer False und wird vom Thread auch irgendwann wieder auf False gesetzt. Das sollte doch sicher sein?

Geändert von luke2 ( 4. Okt 2012 um 15:39 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:46 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz