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 4 von 4   « Erste     234   
SneakyBagels
(Gast)

n/a Beiträge
 
#31

AW: Critical Section um globale Methode?

  Alt 7. Jun 2017, 19:02
Zitat:
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.
Danke! Muss ich heute Abend noch einmal ausführlich testen!

Wenn BeginRead nur dafür da ist zu verhindern, dass kein Write ausgeführt werden kann, lasse ich das vermutlich weg denn es gibt genau eine einzige Stelle an der geschrieben wird.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

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

AW: Critical Section um globale Methode?

  Alt 7. Jun 2017, 20:50
Wenn BeginRead nur dafür da ist zu verhindern, dass kein Write ausgeführt werden kann, lasse ich das vermutlich weg denn es gibt genau eine einzige Stelle an der geschrieben wird.
Entweder du kannst sicherstellen, dass bei dem Schreibvorgang ohnehin niemand liest, dann brauchst du keinerlei Sperren (sofern beim Lesen alles threadsicher ist).

Oder du kannst nicht ausschließen, dass jemand liest während du schreibst, dann musst du dies durch Sperren sicherstellen, in dem Fall durch den TMultiReadExclusiveWriteSynchronizer. Dann musst du dem aber auch sagen wann du lesen und wann schreiben möchtest, damit er diese Sperre auch durchführen kann.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
SneakyBagels
(Gast)

n/a Beiträge
 
#33

AW: Critical Section um globale Methode?

  Alt 7. Jun 2017, 21:06
Ist bei mir ganz einfach: es ist exakt eine einzige Zeile Code im Multithread-System, die schreibenden Zugriff hat.
Es gibt eine weitere solche Zeile, die hat aber nichts mit Multithreading zu tun.

Es ist egal von wo aus ich TMultiReadExclusiveWriteSynchronizer aufrufe, oder muss das aus dem Thread heraus sein der schreiben möchte?
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

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

AW: Critical Section um globale Methode?

  Alt 8. Jun 2017, 06:45
Es ist egal von wo aus ich TMultiReadExclusiveWriteSynchronizer aufrufe, oder muss das aus dem Thread heraus sein der schreiben möchte?
Ich glaube ich hole besser noch einmal weiter aus bevor ich das beantworte.

Du musst vor jedem Schreibvorgang BeginWrite aufrufen (ab da werden alle Schreib- und Lesezugriffe blockiert) und nach dessen Abschluss EndWrite (dann können wieder alle lesen).

Vor jedem Lesevorgang musst du BeginRead aufrufen (ab da wartet BeginWrite, falls es danach aufgerufen wird, auf den Abschluss des Lesevorgangs) und nach dessen Abschluss EndRead (danach kehrt BeginWrite zurück, falls es nach BeginRead aufgerufen wurde.

Auf diese Weise kann ein Schreibvorgang erst nach Abschluss aller laufenden Lesevorgänge passieren und neue Lesevorgänge erst nach dem Abschluss eines laufenden Schreibvorgangs.
Solange aber niemand schreibt, können alle parallel lesen, d.h. BeginRead..EndRead kann beliebig parallel laufen.

Um zur Frage zurückzukommen:
Im Prinzip ist es egal aus welchem Threadkontext du BeginWrite..EndWrite aufrufst solange es vor bzw. nach dem Schreibvorgang passiert. Wann der passiert, sollte ein anderer Thread aber in der Regel (es gibt Ausnahmen, ja) gar nicht kontrollieren, weshalb die praktische Antwort meistens Nein ist, auch wenn es technisch egal ist.

Genau lässt sich das aber nur sagen, wenn man den konkreten Ablauf kennt. Es würde auch abstrakt ohne Code genügen, z.B. auch als Diagramm, wer (Thread XY) wann (während andere Threads laufen? autark? kontrolliert durch einen anderen Thread? ...) was (Schreiben oder Lesen) macht, um einen Überblick zu haben.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
HolgerX

Registriert seit: 10. Apr 2006
Ort: Leverkusen
972 Beiträge
 
Delphi 6 Professional
 
#35

AW: Critical Section um globale Methode?

  Alt 8. Jun 2017, 09:32
Hmm..

Der Zugriff erfolgt vergleichbar einer TCriticalSection.

Beispiel:

Delphi-Quellcode:
unit Unit2;

interface

uses
  SysUtils;

function LeseDaten : string;
procedure SchreibeDaten(Value : string);

implementation

var
  MSync_Global : TMultiReadExclusiveWriteSynchronizer;

  Daten_Test : string;

function LeseDaten : string;
begin
  MSync_Global.BeginRead;
  try
    Result := Daten_Test;
  finally
    MSync_Global.EndRead;
  end;
end;

procedure SchreibeDaten(Value : string);
begin
  MSync_Global.BeginWrite;
  try
    Daten_Test := Value;
  finally
    MSync_Global.EndWrite;
  end;
end;

initialization
  MSync_Global := TMultiReadExclusiveWriteSynchronizer.Create;

finalization
  MSync_Global.Free;

end.

Alle Threads (auch der Main..) nutzen nun einfach

function LeseDaten : string;
procedure SchreibeDaten(Value : string);

für den Zugriff auf 'Daten_Test : string;'.

Durch die Verwendung des globalen 'MSync_Global : TMultiReadExclusiveWriteSynchronizer;' innerhalb der Funktionen ist der Zugriff Threadsave..

(Einfach nur mal so Runtergeschrieben als minimales Beispiel )
(Fehler und Irtümer nicht ausgeschlossen )
  Mit Zitat antworten Zitat
SneakyBagels
(Gast)

n/a Beiträge
 
#36

AW: Critical Section um globale Methode?

  Alt 8. Jun 2017, 10:59
Genau lässt sich das aber nur sagen, wenn man den konkreten Ablauf kennt. Es würde auch abstrakt ohne Code genügen, z.B. auch als Diagramm, wer (Thread XY) wann (während andere Threads laufen? autark? kontrolliert durch einen anderen Thread? ...) was (Schreiben oder Lesen) macht, um einen Überblick zu haben.
Wie eine Seite zuvor beschrieben, hier mit Pseudo-Code.


Delphi-Quellcode:
// Andere Unit erzeugt die Threads aus dem Mainthread heraus
erzeuge Thread 1+2+3 und gebe jedem ein Teil aus einer großen Liste; // (ja ich weiß, es gibt TParallel.For :P )


// Die Thread-unit selber
-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;
Wie man sieht gibt es genau eine einzige Stelle in dieser Thread-Unit, wo geschrieben wird. Alles danach ist nur noch lesen.

Geändert von SneakyBagels ( 8. Jun 2017 um 11:01 Uhr)
  Mit Zitat antworten Zitat
HolgerX

Registriert seit: 10. Apr 2006
Ort: Leverkusen
972 Beiträge
 
Delphi 6 Professional
 
#37

AW: Critical Section um globale Methode?

  Alt 8. Jun 2017, 15:54
Delphi-Quellcode:
// Andere Unit erzeugt die Threads aus dem Mainthread heraus
erzeuge Thread 1+2+3 und gebe jedem ein Teil aus einer großen Liste; // (ja ich weiß, es gibt TParallel.For :P )


// Die Thread-unit selber
-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;
Wie man sieht gibt es genau eine einzige Stelle in dieser Thread-Unit, wo geschrieben wird. Alles danach ist nur noch lesen.

Um das Sync zu machen, musst du dennoch von jedem Lesen 'BeginRead' und danach 'EndRead' machen! Nur fürs Schreiben BeginWrite/EndWrite reicht nicht!
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 4 von 4   « Erste     234   


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 16:56 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