AGB  ·  Datenschutz  ·  Impressum  







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

Critical Section um globale Methode?

Ein Thema von Rabenrecht · begonnen am 5. Mai 2017 · letzter Beitrag vom 8. Jun 2017
Antwort Antwort
Seite 3 von 4     123 4      
Benutzerbild von himitsu
himitsu

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

AW: Critical Section um globale Methode?

  Alt 7. Jun 2017, 16:16
Das verstehe ich jetzt nicht. Wofür denn nun Monitor und eine CS?
Im Prinzip ist Beides das Gleiche, nur mit 'ner anderen Syntax.

Ist wie der unterschied zwischen StringList[123] und StringList.Strings[123] .



Abgesehn, dass TMonitor was "Eigenes" ist und TCriticalSection die API vom Windows kapselt, aber von der Funktion her sind die schon vergleichbar.
$2B or not $2B
  Mit Zitat antworten Zitat
SneakyBagels
(Gast)

n/a Beiträge
 
#22

AW: Critical Section um globale Methode?

  Alt 7. Jun 2017, 16:19
Ok dann bleibe ich wohl bei CriticalSections.
Die sind mir vom Aufbau her so oder so logischer.
Ich selber konnte bei meinen Tests keinerlei Performanceunterschied feststellen.
Scheinen wohl nur Nanosekunden zu sein.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Critical Section um globale Methode?

  Alt 7. Jun 2017, 16:23
In Delphi gibt es noch viel mehr Implementationen, die das Gleiche wie eine CriticalSection/TMonitor erledigen.

Dann noch paar Dinger mit Zusatzfunktionen, wie z.B. den TMultiReadExclusiveWriteSynchronizer (TMREWSync), welcher parallele Lesezugriffe erlaubt und nur bei einem Schreibzugriff alles komplett sperrt.
Und für Zugriffe auf einzelne Interger, Pointer, Booleans und anderen Kleinkram gibt es mehrere Interlocked-Implementationen, welche atomare Schreibzugriffe ermöglichen.
$2B or not $2B

Geändert von himitsu ( 7. Jun 2017 um 16:26 Uhr)
  Mit Zitat antworten Zitat
SneakyBagels
(Gast)

n/a Beiträge
 
#24

AW: Critical Section um globale Methode?

  Alt 7. Jun 2017, 16:37
Zitat:
Dann noch paar Dinger mit Zusatzfunktionen, wie z.B. den TMultiReadExclusiveWriteSynchronizer (TMREWSync), welcher parallele Lesezugriffe erlaubt und nur bei einem Schreibzugriff alles komplett sperrt.
Das ist interessant zu wissen! Ich dachte immer nur, hier würde nur für lesenden Zugriff gesperrt.
Aber heißt das jetzt, dass sobald ich bei Verwendung von TMultiReadExclusiveWriteSynchronizer irgendwo trotzdem schreibe, nur dieser eine schreibende Zugriff geblockt wird?
Wenn ja dann wäre das ja ein recht großer Vorteil denn statt 100 von 100 "Dingern" zu blocken (wo ich 1x schreibe und 99x lese) würde hier nur 1x geblockt. Sehe ich das richtig?

Dass ich schreibenden Zugriff hier mit BeginWrite und EndWrite absichern muss ist klar. Aber wofür den lesenden?

Edit:
durch die Verwendung eines globalen TMultiReadExclusiveWriteSynchronizer und BeginWrite/EndWrite, welches ich NUR dort verwende wo ich meiner Klasseninstanz Daten zuweise, ist meine Prozedur rund 5% schneller geworden. Kann das daran liegen, dass ich nun nicht mehr rigoros alles blockiere sondern nur noch den schreibenden Zugriff?

Geändert von SneakyBagels ( 7. Jun 2017 um 16:50 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

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

AW: Critical Section um globale Methode?

  Alt 7. Jun 2017, 17:01
durch die Verwendung eines globalen TMultiReadExclusiveWriteSynchronizer und BeginWrite/EndWrite, welches ich NUR dort verwende wo ich meiner Klasseninstanz Daten zuweise, ist meine Prozedur rund 5% schneller geworden. Kann das daran liegen, dass ich nun nicht mehr rigoros alles blockiere sondern nur noch den schreibenden Zugriff?
Korrekt. Der TMultiReadExclusiveWriteSynchronizer ist für solche Szenarien besser geeignet, als TCriticalSection oder TMonitor . Solange jetzt n-Threads gleichzeitig NUR lesen, wirst du einen Performancevorteil feststellen können. Im Grunde stellt der TMultiReadExclusiveWriteSynchronizer jetzt nur noch sicher, dass erst alle lesenden Zugriffe abgeschlossen sind, bevor ein schreibender Zugriff stattfindet und blockiert während dieser Zeit dann alle lesenden Operationen (deshalb musst du trotzdem signalisieren, an welchen Stellen du lesen willst).

Mit TCriticalSection oder TMonitor hingegen, kann auch nur ein einziger Thread gleichzeitig lesen.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Critical Section um globale Methode?

  Alt 7. Jun 2017, 17:12
Lesezugriffe sperren sich nicht gegenseitig ... mehrere sind erlaubt.
So lange es Lesesperren gibt, warten alle Schreibanfragen.
Eine Schreibsperre sperrte alle anderen Lese und Schreibzugriffe.

Natürlich nur verwendbar für "echte" Lesezugriffe, wo wirklich nichts geschrieben wird.
z.B. Stream.Read ist zwar ein Lesezugriff, aber da bei wird der Positionszeiger geändert, was einen Schreibzugriff darstellt.

Aber sonst können mehrere ungehindert gleichzeitig lesen
und wenn Einer was schreiben will, dann ist so lange alles gesperrt.
MultiReader ist demnach besonders hilfreich, bei vielen Lesezugriffen und seltenen Schreibzugriffen.

Bei der CriticalSection und dem TMonitor ist immer alles gesperrt, egal ob lesen oder schreiben.
(nur Zugriffe aus dem selben Thread sind erlaubt, da sie per se threadsave sind und man so keinen Deadlock riskiert, wenn man in einem Thread verschachtelt Enter aufruft)
$2B or not $2B
  Mit Zitat antworten Zitat
SneakyBagels
(Gast)

n/a Beiträge
 
#27

AW: Critical Section um globale Methode?

  Alt 7. Jun 2017, 17:58
Mhhh ok das heißt also

Delphi-Quellcode:
-thread-instanzen 1+2+3 (alle selber Code, nur unterschiedliche Listen sind abzuarbeiten)
begin
 schleife anfang

 _globals.aMultiReadExclusiveWriteSynchronizer.BeginWrite;
 setze globale Klasseninstanz := Liste.Items[i]
 _globals.aMultiReadExclusiveWriteSynchronizer.EndWrite;

 (a)
 ...
 lese hier
 ...
 lese dort
 ...
 lese nochmals hier
 (b)

 schleife ende
end;
So habe ich das aktuell. Jeder Thread kann der globale Klasseninstanz ein Item zuweisen. An anderen Stellen (nicht in diesem Thread) lese ich die Klasseninstanz dann aus und zeige die dahinterliegenden Daten auf der Benutzeorberfläche an.

Ist das so richtig oder müsste ich jetzt noch zusätzlich von (a) bis (b) ein _globals.aMultiReadExclusiveWriteSynchronizer.Begi nRead; und EndRead setzen?

Geändert von SneakyBagels ( 7. Jun 2017 um 18:02 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Critical Section um globale Methode?

  Alt 7. Jun 2017, 18:35
Dort, wo lesend auf globale-Klasseninstanz zugegriffen wird, kommt natürlich ein BeginRead drumrum.

Erstmal reicht es den Lese-Zugriff auf diese Variable zu sperren,
aber wenn sich innerhalb dieser Instanz auch etwas ändern kann (Property und enthaltene Variablen), dann auch das mit einschließen.

Wenn sich an der Objektinstanz nicht gleichzeig in mehreren Thread was ändert,
also z.B. da was einstellen, dann die Variable setzen und jemand Anderes liest dann nur diese Variable, oder holt sich sie da raus (auslesen und NIL setzen),
dann kann man auch mit InterlockedExcange oder den neuen TLock-irgendwas-Klassen in der System-Unit arbeiten.
$2B or not $2B

Geändert von himitsu ( 7. Jun 2017 um 18:38 Uhr)
  Mit Zitat antworten Zitat
SneakyBagels
(Gast)

n/a Beiträge
 
#29

AW: Critical Section um globale Methode?

  Alt 7. Jun 2017, 18:39
Da achte ich strikt drauf. Erst ändere ich und dann lese ich. Danach wird erstmal nicht mehr geändert. Im jedem Schleifendurchgang gibt es nur eine einzige Änderung.
Wofür ist es denn wichtig den lesenden Zugriff zu sperren?
Wenn man 5 Thread-Instanzen hat, alle haben die gleichen Dinge abzuarbeiten, man aber den lesen Zugriff blockieren muss, kann man dann hier überhaupt noch von Multithreading reden?

Erste Tests zeigen, dass wenn ich überall den lesenden Zugriff blockiere der Code doppelt so lange braucht als vorher.
Den lesenden Zugriff hatte ich früher noch nie blockiert, immer nur den schreibenden.

Geändert von SneakyBagels ( 7. Jun 2017 um 18:44 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Critical Section um globale Methode?

  Alt 7. Jun 2017, 18:53
Die Lesedinge sperren sich dabei nicht gegenseitig.

Das BeginRead ist nur dafür da, um zu verhindern, dass jemand während des Lesens etwas ändern kann.
BeginRead sperrt das BeginWrite, bzw. hält selber an, wenn gerade geschrieben wird.
Andere BeginRead werden aber durch den Read-Lock (durch BeginRead) nicht beeinflusst.
$2B or not $2B
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 4     123 4      


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 22:25 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz