AGB  ·  Datenschutz  ·  Impressum  







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

CriticalSections wie verwenden?

Ein Thema von Bummi · begonnen am 28. Nov 2010 · letzter Beitrag vom 21. Mai 2017
Antwort Antwort
Benutzerbild von Assarbad
Assarbad

Registriert seit: 8. Okt 2010
Ort: Frankfurt am Main
1.234 Beiträge
 
#1

AW: CriticalSections wie verwenden?

  Alt 28. Nov 2010, 01:48
hier hakt es bei mir, wofür brauche ich hier dann lokale (innerhalb des Threads gültige) CriticalSections.
Jupp, tut mir leid. Hatte das Originalthema nicht komplett gelesen und auch jetzt nur überflogen. Aber der Code bei dem jeder Thread seine eigene CS hat, ist natürlich Unsinn. Ein Synchronisationsobjekt funktioniert nur wenn alle das gleiche benutzen. Oder um Luckie zu zitieren:

Wenn mehrere Threads aufeinander warten müssen, dann dürfen sie auch nur die gleiche CriticalSection nutzen. Das ist wie bei einer Ampelkreuzung, die darf auch nur von einer Schaltung gesteuert werden. Hätte jede Ampel ihre eigene Steuerung würde es krachen.
Oliver
"... aber vertrauen Sie uns, die Physik stimmt." (Prof. Harald Lesch)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: CriticalSections wie verwenden?

  Alt 28. Nov 2010, 02:12
hier hakt es bei mir, wofür brauche ich hier dann lokale (innerhalb des Threads gültige) CriticalSections.
Jupp, tut mir leid. Hatte das Originalthema nicht komplett gelesen und auch jetzt nur überflogen. Aber der Code bei dem jeder Thread seine eigene CS hat, ist natürlich Unsinn. Ein Synchronisationsobjekt funktioniert nur wenn alle das gleiche benutzen.
Hmmm, das sehe ich anders, wenn ich optimal laufenden Code erzeugen will mit der maximal möglichen Performance. Natürlich wird es auch mit einer externen CS funktionieren, aber eben nicht so performant wie es laufen könnte.

Beispiel:
Delphi-Quellcode:
GlobalCS : TCriticalSection;

TMyThread = class( TThread )
{...}
  Info : Int64;
end;

procedure TMyThread.Execute;
  begin
    while not Terminated do
      begin
        GlobalCS.Enter;
        try
          QueryPerformanceCounter( Info );
        finally
          GlobalCS.Leave;
        end;
      end;
  end;

MyThread1, MyThread2 : TMyThread;

procedure ImMainThread;
var
  ThInfo : Int64;
begin
  GlobalCS.Enter;
  // Beide Threads MyThread1, MyThread2 stoppen jetzt, weil sie ja
  // GlobalCS nicht mehr betreten können.
  // Ich will aber nur von MyThread1 etwas wissen, warum soll MyThread2 dann gestört werden???
  try
    ThInfo := MyThread1.Info;
  finally
    GlobalCS.Leave;
  end;
end;
Meine Variante sieht so aus
Delphi-Quellcode:

TMyThread = class( TThread )
  ThreadCS : TCriticalSection;
  FInfo : int64;
{...}
  property Info : Int64 read GetInfo;
end;

function GetInfo : Int64;
  begin
    ThreadCS.Enter;
    try
      Result := FInfo;
    finally
      ThreadCS.Leave;
    end;
  end;

procedure TMyThread.Execute;
  begin
    while not Terminated do
      begin
        ThreadCS.Enter;
        try
          QueryPerformanceCounter( FInfo );
        finally
          ThreadCS.Leave;
        end;
      end;
  end;

MyThread1, MyThread2 : TMyThread;

procedure ImMainThread;
var
  ThInfo : Int64;
begin
  ThInfo := MyThread1.Info;
end;
Der Zugriff auf die Property ist wesentlich leichter und es wird nur der Thread gestört, den ich abfrage.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (28. Nov 2010 um 02:23 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Assarbad
Assarbad

Registriert seit: 8. Okt 2010
Ort: Frankfurt am Main
1.234 Beiträge
 
#3

AW: CriticalSections wie verwenden?

  Alt 28. Nov 2010, 02:24
Hmmm, das sehe ich anders, wenn ich optimal laufenden Code erzeugen will mit der maximal möglichen Performance. Natürlich wird es auch mit einer externen CS funktionieren, aber eben nicht so performant wie es laufen könnte.
Nunja, Synchronisation muß aber nunmal sein.

Meine Delphikenntnisse sind ein wenig eingerostet, aber ich sehe in deinem Code keinen konkurrierenden Zugriff zwischen den Threads. Was willst du also beweisen? Daß dein Code sicher ist, wäre zumindest damit nicht (generell) bewiesen.

Greift Thread A auf eine Property aus Thread B zu, dann ist die Property von Thread B ja geschützt. Somit kann es einfach keine Zugriffsfehler geben, da diese immer geschützt sind.
Die Aussage macht allerdings in der Tat Sinn, wenn ein Zugriff so wie beschrieben stattfände.

Das was ich gesehen habe wäre aber ohnehin billiger mit Interlocked-Funktionen zu machen (zumindest bei den verwendeten Datentypen).

Wenn Du für jede Instanz eine eigene CS erzeugst wie soll der Zugriff dann geschützt sein.
Wenn jeder Thread seine eigene Queue hat und mit der CS schützt, dann macht es schon so Sinn. Da der Zugriff über Getter/Setter stattfindet, hat alles seine Ordnung.

Zusammenfassend:

Also, es gibt nicht nur eine Queue, somit ist die Queue auch pro Thread schützbar (so wie gezeigt).
Oliver
"... aber vertrauen Sie uns, die Physik stimmt." (Prof. Harald Lesch)

Geändert von Assarbad (28. Nov 2010 um 02:28 Uhr)
  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 02:18 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