Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

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

AW: TDictionary und TThread

  Alt 26. Feb 2020, 01:01
TCriticalSection ist ja Windows MSDN-Library durchsuchenEnterCriticalSection, auch wenn Delphi diese Klasse schon für andere Plattformen erweitert hat.

Hier könnte man zwar auch einen MultiReaderSingleWriter verwenden, da sich das Dictionary parallel auslesen ließe, aber wenn nicht soooooo oft gelesen wird, dann lohnt es sich nicht.
Delphi-Referenz durchsuchenTSimpleRWSync bzw. Delphi-Referenz durchsuchenTMultiReadExclusiveWriteSynchronizer/TMREWSync

Dann gibt es noch das "neuere" TMonitor in der System-Unit, welches sich nativ an jedes TObject hängen lässt. (mit dem Namen der nicht mit TMonitor aus Forms zu verwechseln ist)

Es gibt auch eine TThreadList, was eine TList ist und bereits sowas wie eine CriticalSection enthält.
Add, Remove und Clear sind bereits threadsave und ansonsten kann man sich die innere TList auch gesperrt rausholen und längere Aktionen mit der Liste machen, während die anderen Threads warten.

Und im Grunde kommt kommt alles auf's Gleiche drauf raus, du mußt die Liste sperren (mindestens) wenn die Liste bearbeitet wird, bzw. auch für die "kurze" Rechenpause zwischen Nachsehn und das Machen.
Delphi-Quellcode:
TMonitor.Enter(List);
try
  if not List.Find(xyz) then
    List.Add(xyz);
finally
  TMonitor.Exit(List);
end;
Atomare Operationen braucht man nicht selbst absichern, wie z.B. InterlockedIncrement bzw. das plattformunabhängige AtomicIncrement oder das TThreadList.Add,
aber alles Andere muß geschützt werden, wie z.B. im Beispeispiel die Lücke zwischen If, Find und Add, wo ja ein anderer Thread zwischendurch das auch einfügen kann und das Ergebnis vom IF somit schon nicht mehr stimmt, wenn Add ausgeführt wird.

Alle anderen Sperr-Klassen mußt du ja neben dein zu Sperrendes legen, während TMonior direkt an der Klasse hängt, aber mit dem "Nachteil", dass man in der Definition nichts von dieser Sperr-Instanz sieht.
Hier kann man aber das Verhalten des Compilers ausnutzen, dass er unbekannte Attributklassen einfach ignoriert,
um hier in der Deklaration zu "dokumentieren", dass unten TMonitor verwendet wird.
Delphi-Quellcode:
var
  [Monitor] // oder [Lock]
  List: TDictionary<string,string>;
Delphi-Quellcode:
type
  MonitorAttribute = class(TAttribute);

var
  [Monitor]
  List: TDictionary<string,string>;
PS: Globale Variablen sind eh böse und ich würde das Dictionary als Class Var in die Threadklasse integrieren.
Delphi-Quellcode:
type
  TMyThread = class(TThread)
  public class var
    List: TDictonary<string,string>;
  protected
    procedure Execute; override;
  end;

// von außerhalb
TMyThread.List[abx] := def; //TMyThread.List.Add(abx, def);
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (26. Feb 2020 um 01:23 Uhr)
  Mit Zitat antworten Zitat