![]() |
Synchronisierung zwischen Threads ohne Mutex
Hallo zusammen,
ich habe eine Frage, wie man folgendes anders lösen kann: globale Liste Task 1 (Thread): zyklischer Check der kompletten Liste und irgendwelche Aktionen damit machen Task 2 (Thread): Löschen und Hinzufügen von Einträgen in der globalen Liste Es geht hier NICHT um VCL und Synchronize. Das ganze kann man mit einer Mutex machen und bevor jemand mit der globalen Liste etwas machen möchte, wird sich die Mutex gezogen und nur wenn man diese bekommt (also kein anderer Besitzer vorhanden ist), hat man den Zugriff auf die globale Liste. Das funktioniert und darauf möchte ich auch nicht weiter eingehen. Ich möchte nur wissen, welche Mechanismen es noch gibt, eine derartige Synchronisation zwischen den Threads zu machen. Natürlich erledigen die Threads noch andere Aufgaben, dass ist nur eine Teilbeschreibung. Zum allgemeinen Hintergrund warum das Ganze: Wenn Task 1 gerade in einer Schleife über alle Items ist und Task 2 gerade Items löscht oder hinzufügt, dann knallt es in Task 1 |
AW: Synchronisierung zwischen Threads ohne Mutex
![]() |
AW: Synchronisierung zwischen Threads ohne Mutex
Wenn es um einfache Benutzerbarkeit geht, gibt es System.Generics.Collections.TThreadList<T>, die das Locking intern über TMonitor regelt.
Wie oft passieren denn Lese- und Schreibzugriffe? Wenn Schreibzugriffe im Vergleich deutlich seltener als Lesezugriffe sind (die ja nicht gegenseitig synchronisiert werden müssen, solange kein Schreibzugriff passiert), gibt es System.SyncObjs.TLightweightMREW, das für diesen Fall sehr performant ist. Das sorgt dafür, dass jeder lesen kann wie er möchte, aber ein Schreibzugriff nur exklusiv passiert. Ich habe die Formulierung aufgrund von Peters Hinweis angepasst. Und natürlich muss man bei TLightweightMREW auch einen logischen Lesezugriff komplett absichern. Wenn der also in einem Block mit einer Schleife passiert, muss man den Block insgesamt als Lesezugriff absichern. |
AW: Synchronisierung zwischen Threads ohne Mutex
Zitat:
|
AW: Synchronisierung zwischen Threads ohne Mutex
Zitat:
|
AW: Synchronisierung zwischen Threads ohne Mutex
Danke für die Anregungen.
Werde mich mal mit TMonitor beschäftigen. Habt ihr da mal ein einfaches Beispiel, wie man das damit machen könnte? |
AW: Synchronisierung zwischen Threads ohne Mutex
Du musst lediglich ein Objekt angeben, das für die Identifizierung der Sperre verwendet wird. Da es hier um Zugriffe auf eine Liste geht, bietet es sich an, diese auch zu verwenden.
Delphi-Quellcode:
Entsprechend mit Angabe des Starts und Endes des Blocks funktionieren auch die andere Varianten wie z.B. TLightweightMREW:
TMonitor.Enter(MyList);
try MyList.Add(42); finally TMonitor.Exit(MyList); end;
Delphi-Quellcode:
Wichtig ist try..finally, um sicherzustellen, dass auch bei einem Fehler die Sperre wieder aufgehoben wird.
var
Lock: TLightweightMREW; Test: Integer; begin Lock.BeginWrite; // Schreibzugriff anfordern try MyList.Add(42); finally Lock.EndWrite; end; Lock.BeginRead; // Lesezugriff anfordern try Test := MyList[0]; finally Lock.EndRead; end; |
AW: Synchronisierung zwischen Threads ohne Mutex
Delphi-Quellcode:
Das heißt, wenn ich in dem try-Abschnitt (zwischen dem .Enter und .Exit) mit Task 1 bin, bleibt eine Task 2 im ".Enter" hängen, solange die Task 1 das ".Exit" nicht durchgeführt hat im finally?
TMonitor.Enter(MyList);
try MyList.Add(42); finally TMonitor.Exit(MyList); end; |
AW: Synchronisierung zwischen Threads ohne Mutex
TMonitor ist eine CriticalSection die Du nicht global deklariert hast sondern die seit Delphi Version *MPF* in jedem Nachfahren von TObjekt deklariert ist.
Dadurch kann du also einzelne Objekte für alle threads in denen sie benutzt werden als "in Benutzung" markieren und wieder freigeben. Wenn du alle Verwendungen eines Objekts mit TMonitor einrahmst, dann ist das Objekt über verschiedene threads hinweg als gemeinsame Resource sicher nutzbar. |
AW: Synchronisierung zwischen Threads ohne Mutex
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:58 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 by Thomas Breitkreuz