AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Synchronisierung zwischen Threads ohne Mutex
Thema durchsuchen
Ansicht
Themen-Optionen

Synchronisierung zwischen Threads ohne Mutex

Ein Thema von AJ_Oldendorf · begonnen am 28. Jan 2025 · letzter Beitrag vom 30. Jan 2025
Antwort Antwort
AJ_Oldendorf

Registriert seit: 12. Jun 2009
397 Beiträge
 
Delphi 12 Athens
 
#1

Synchronisierung zwischen Threads ohne Mutex

  Alt 28. Jan 2025, 10:21
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
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.646 Beiträge
 
Delphi 12 Athens
 
#2

AW: Synchronisierung zwischen Threads ohne Mutex

  Alt 28. Jan 2025, 10:37
https://docwiki.embarcadero.com/Libr...ystem.SyncObjs, da kannst Du Dir das Passende aussuchen, System.TMonitor sollte IMO aber auch funktionieren.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.743 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Synchronisierung zwischen Threads ohne Mutex

  Alt 28. Jan 2025, 12:14
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.
Sebastian Jänicke
AppCentral

Geändert von jaenicke (28. Jan 2025 um 13:50 Uhr)
  Mit Zitat antworten Zitat
peterbelow

Registriert seit: 12. Jan 2019
Ort: Hessen
709 Beiträge
 
Delphi 12 Athens
 
#4

AW: Synchronisierung zwischen Threads ohne Mutex

  Alt 28. Jan 2025, 12:53
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 synchronisiert werden müssen), gibt es System.SyncObjs.TLightweightMREW, das für diesen Fall sehr performant ist.
Vorsicht! Lesezugriffe auf eine Liste müssen durchaus synchronisiert werden, wenn ein anderer Thread die Zahl oder Reihenfolge der Items ändern kann, besonders, wenn das Lesen in einer Schleife erfolgt.
Peter Below
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.743 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Synchronisierung zwischen Threads ohne Mutex

  Alt 28. Jan 2025, 13:48
Vorsicht! Lesezugriffe auf eine Liste müssen durchaus synchronisiert werden, wenn ein anderer Thread die Zahl oder Reihenfolge der Items ändern kann, besonders, wenn das Lesen in einer Schleife erfolgt.
Das war missverständlich. Ich meinte das in Bezug auf mehrere Lesezugriffe und TLightweightMREW, aber das muss man natürlich beim Lesen und Schreiben verwenden. Ich korrigiere die Formulierung. Danke.
Sebastian Jänicke
AppCentral

Geändert von jaenicke (28. Jan 2025 um 14:07 Uhr)
  Mit Zitat antworten Zitat
AJ_Oldendorf

Registriert seit: 12. Jun 2009
397 Beiträge
 
Delphi 12 Athens
 
#6

AW: Synchronisierung zwischen Threads ohne Mutex

  Alt 29. Jan 2025, 07:19
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?
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.743 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Synchronisierung zwischen Threads ohne Mutex

  Alt 29. Jan 2025, 23:27
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:
  TMonitor.Enter(MyList);
  try
    MyList.Add(42);
  finally
    TMonitor.Exit(MyList);
  end;
Entsprechend mit Angabe des Starts und Endes des Blocks funktionieren auch die andere Varianten wie z.B. TLightweightMREW:
Delphi-Quellcode:
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;
Wichtig ist try..finally, um sicherzustellen, dass auch bei einem Fehler die Sperre wieder aufgehoben wird.
Sebastian Jänicke
AppCentral

Geändert von jaenicke (30. Jan 2025 um 07:05 Uhr)
  Mit Zitat antworten Zitat
AJ_Oldendorf

Registriert seit: 12. Jun 2009
397 Beiträge
 
Delphi 12 Athens
 
#8

AW: Synchronisierung zwischen Threads ohne Mutex

  Alt 30. Jan 2025, 09:02
Delphi-Quellcode:
  TMonitor.Enter(MyList);
  try
    MyList.Add(42);
  finally
    TMonitor.Exit(MyList);
  end;
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?
  Mit Zitat antworten Zitat
QuickAndDirty

Registriert seit: 13. Jan 2004
Ort: Hamm(Westf)
1.958 Beiträge
 
Delphi 12 Athens
 
#9

AW: Synchronisierung zwischen Threads ohne Mutex

  Alt 30. Jan 2025, 09:09
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.
Andreas
Monads? Wtf are Monads?
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.743 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: Synchronisierung zwischen Threads ohne Mutex

  Alt 30. Jan 2025, 09:25
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?
Ja, das ist richtig. Und bei der TLightweightMREW können beliebig viele parallel lesen, aber sobald ein Schreibzugriff angefordert wird, wird im BeginWrite gewartet, bis alle Zugriffe beendet sind (und es darf niemand mehr rein, auch nicht nur lesend) und dann wird exklusiv der Schreibblock betreten.
Sebastian Jänicke
AppCentral
  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 17:06 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