Delphi-PRAXiS
Seite 3 von 5     123 45   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi CriticalSections wie verwenden? (https://www.delphipraxis.net/156318-criticalsections-wie-verwenden.html)

Bummi 28. Nov 2010 02:01

AW: CriticalSections wie verwenden?
 
@jaenicke
Nochmals Danke
dies ist mir meine ich klar, aber wofür dann die CS wenn sich ohnehin alles innerhalb des Threads abspielt.
Ich scheine hier tatsächlich einen resistenten Hänger zu haben, mir erschließt sich der Sinn der lokalen CS nicht, die ja nur berücksichtigt werden können wenn ein potentieller "Zugreifer" davon Kenntnis hat.

jaenicke 28. Nov 2010 02:05

AW: CriticalSections wie verwenden?
 
Zitat:

Zitat von Bummi (Beitrag 1064548)
aber wofür dann die CS wenn sich ohnehin alles innerhalb des Threads abspielt.

Tut es ja nicht. Ein anderer Thread (z.B. der Hauptthread) greift über die Eigenschaften des Zielthreads aus seinem Kontext zu. Innerhalb des Getters bzw. Setters wird dann über die kritische Sektion des Zielthreads, zu dem die Eigenschaft gehört, verhindert, dass gleichzeitig von innerhalb des Zielthreads darauf zugegriffen wird.

Sir Rufo 28. Nov 2010 02:07

AW: CriticalSections wie verwenden?
 
Zitat:

Zitat von Bummi (Beitrag 1064545)
Jepp, aber hier kommen wir wieder zu dem Punkt daß die Abfrage sich nicht für Deine lokalen CS interessiert.
wenn Du nochmals mein Beispiel aus
http://www.delphipraxis.net/156304-v...ml#post1064523
#26 heranziehst
Meine Vorstellung einer CS basiert darauf daß ein Codeabschnitt markiert Windows mitgeteilt wird. Wenn ein anderer Thread versucht diesen Codeabschnitt zu betreten wird dies nur ermöglicht wenn kein anderer Thread sich gerade darin aufhält. Wenn die Markierung jedes mal eine andere ist wie soll Windows hier eingreifen.

Wenn ich Speicherbereich A schützen möchte, dann nehme ich dafür ein CS mit Namen CSA.
Ich muss nun gewährleisten, dass bei jedem Zugriff auf den Speicherbereich A die CS CSA betreten und danach wieder verlassen wird.

Das ist erstmal alles.

Windows ist es egal, wieviele CS ich benutze.

Jede Instanz von einer Klasse/Thread belegt einen bestimmten Speicherbereich. Erzeuge ich mit der Klasse/Thread eine CS kann ich damit genau den Speicherbereich vom der Klassen-/Thread-Instanz schützen.

Meine Vorgehensweise ist nun, dass alles in der Klasse/Thread, auf das von außen zugegriffen wird von eben so einer CS geschützt wird.

Delphi-Quellcode:
TMyThread = class( TThread )
  property Info : Int64 read GetInfo;
end;

function TMyThread.GetInfo : Int64;
  begin
    ThreadCS.Enter;
    try
      Result := FInfo;
    finally
      ThreadCS.Leave;
    end;
  end;
Wenn ich jetzt auf die Property Info von der Thread-Instanz zugreife, warum sollte die dann nicht geschützt sein?
Es wird ein CS betreten, der Wert ausgelesen und die CS wieder verlassen.
Das diese CS-Instanz innerhalb der Thread-Instanz aufgehangen ist, ist völlig egal. Es ist eine CS.

Und schützen muss ich die mit einer CS, wenn ich den Wert der Property Info innerhalb von TMyThread.Execute beschreiben will
Delphi-Quellcode:
procedure TMyThread.Execute;
  begin
    ThreadCS.Enter;
    try
      FInfo := 20;
    finally
      ThreadCS.Leave;
    end;
  end;

Bummi 28. Nov 2010 02:08

AW: CriticalSections wie verwenden?
 
warum funktioniert dann folgendes
http://www.delphipraxis.net/156304-v...ml#post1064523
#26

wenn hier der zugreifende die CS ignoriert, bwz eine ander nimmt bekommt er Zugriff die der Intention der CS wiederspricht.

Assarbad 28. Nov 2010 02:10

AW: CriticalSections wie verwenden?
 
Zitat:

Zitat von Bummi (Beitrag 1064548)
dies ist mir meine ich klar, aber wofür dann die CS wenn sich ohnehin alles innerhalb des Threads abspielt.

Tut es nicht zwangsläufig.

Wir haben Threads A und B sowie Ressourcen a(A) und b(B) die jeweils dem Thread gehören. A besitzt eine CS die den Zugriff auf a(A) regelt und B eine CS die den Zugriff auf b(B) regelt. Soweit kommst du sicher mit, richtig?

Wenn nun aber Thread A einen Zugriff auf die Instanz von B macht, ruft er (im eigenen Kontext, also dem Kontext von Thread A ... das ist der potentielle Konflikt) die Getter oder Setter von B auf (aber mit Self == B). Dieser Getter oder Setter benutzt aber auch die CS welche den Zugriff auf b(B) regelt und damit ist alles in Ordnung.

jaenicke 28. Nov 2010 02:12

AW: CriticalSections wie verwenden?
 
Zitat:

Zitat von Bummi (Beitrag 1064551)
wenn hier der zugreifende die CS ignoriert, bwz eine ander nimmt bekommt er Zugriff die der Intention der CS wiederspricht.

Dort hast du eine Resource und zwei kritische Sektionen, die du für den Zugriff benutzt.

In Sir Rufos Code hast du genau eine kritische Sektion für genau eine Resource.

Sir Rufo 28. Nov 2010 02:15

AW: CriticalSections wie verwenden?
 
Zitat:

Zitat von Bummi (Beitrag 1064551)
warum funktioniert dann folgendes
http://www.delphipraxis.net/156304-v...ml#post1064523
#26

wenn hier der zugreifende die CS ignoriert, bwz eine ander nimmt bekommt er Zugriff die der Intention der CS wiederspricht.

Das läuft im HauptThread
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  tc:Cardinal;
begin
  FCS.Enter;
  txt := 'Button1';
  tc := GetTickCount;
  while GetTickCount < (tc + 5000) do Application.ProcessMessages;
  Showmessage(txt);
  FCS.Leave;
end;
Das im Thread (also in einem anderen Thread als der HauptThread)
Delphi-Quellcode:
procedure TMyThread.Execute;
begin
  inherited;
  FCS2.Enter;
  txt := 'Thread';
  FCS2.Leave;
end;
Das Perverse daran ist, das funktioniert tatsächlich ... aber das hier würde auch funktionieren:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  tc:Cardinal;
begin
  txt := 'Button1';
  tc := GetTickCount;
  while GetTickCount < (tc + 5000) do Application.ProcessMessages;
  Showmessage(txt);
end;

procedure TMyThread.Execute;
begin
  inherited;
  txt := 'Thread';
end;
Erst wenn der HauptThread und der Thread gleichzeitig schreibend/lesend oder schreibend/schreibend auf die Variable txt zugreifen, erst dann und nur dann gibt es einen Zugriffsfehler.

Die CS ist nicht dazu da, dass es überhaupt funktioniert, sondern dass es immer funktioniert.

Allerdings wirst du bei diesem COde es wahrscheinlich niemals eine Zugriffsverletzung bekommen, da der Thread ja nur einen winzigen Moment läuft und genau diesen Zeitpunkt müsstest du treffen, um eine Zugriffsverletzung zu provozieren.
Nach dem Klicken von dem Button für das Starten des Threads, vergeht aber mehr Zeit, bis die Form wieder Eingaben zulässt, als der Thread mit der abarbeitung von Execute benötigt ... darum brauchst du hier gar keine CS, weil der Zustand so gesehen niemals eintrifft :mrgreen:

Bummi 28. Nov 2010 02:19

AW: CriticalSections wie verwenden?
 
dann muss ich allen Beteiligten erst einmal Abbitte leisten. Der Getter/Setter stellt sicher dass ich mich in der richtigen CS befinde, habe ich das richtig verstandenen?

Sir Rufo 28. Nov 2010 02:20

AW: CriticalSections wie verwenden?
 
Zitat:

Zitat von Bummi (Beitrag 1064557)
dann muss ich allen Beteiligten erst einmal Abbitte erleisten. Der Getter/Setter stellt sicher dass ich mich in der richtigen CS befinde, habe ich das richtig verstandenen?

jepp :thumb: u got it

Assarbad 28. Nov 2010 02:26

AW: CriticalSections wie verwenden?
 
Genau.

Ich war auch erstmal verblüfft. Aber Kommentar #9 hat dann auch den Sinn hinter den CS pro Thread aufgezeigt. Ab da war's absolut klar.

Tut mir leid wenn ich zur Verwirrung beigetragen haben sollte. Man sollte eben den kompletten Kontext kennen :zwinker:


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:36 Uhr.
Seite 3 von 5     123 45   

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