AGB  ·  Datenschutz  ·  Impressum  







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

CriticalSection nötig ?

Ein Thema von DataCool · begonnen am 10. Dez 2003 · letzter Beitrag vom 10. Dez 2003
Antwort Antwort
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#1

CriticalSection nötig ?

  Alt 10. Dez 2003, 00:23
Hi Leute,

kurz ne Frage zur CriticalSection:

1. Nehmen wir mal an ich habe innerhalb eines Threads eine private StringListe.
2. Andere Threads können nicht direkt auf die Stringlist zugreifen, sondern nur über den Methode :
Code:
procedure TmyThread.add(Command : String);
begin
   fCmdList.Add(Command);
   if Suspended then
     resume;
end;
3. Die StringList enthält eine Liste von Befehlen die sequentiell abgearbeitet werden sollen, d. h. neue Befehle am Ende hinzufügen und immer das Element 0 in der liste ist der aktuelle Befehl und wird nach der verarbeitung gelöscht.

4. Der Execute Coode des Threads sieht folgendermaßen aus :
Code:
procedure TmyThread.Execute;
begin
   repeat
      while fCmdList.Count > 0 do begin
         doCommand;;
         if fChatList.Count > 0 then // nötig ??
           sleepEx(100,true);
      end;
      // nichts mehr in der Warteschlange --> Thread schlafen legen
      Suspend;
   until Terminated;
end;
So, jetzt meine Fragen :

Da TStringList ja nicht Thread sicher ist, muss ich hier mit CriticalSection arbeiten ?
Obwohl ich von aussen nur immer Elemente am ende der liste hinzufüge ?
Wenn ich mit CriticalSection arbeite, dann nur bei Delete der stringliste oder auch beim Add ?

Irgentwo hab ich mal gelesen das CriticalSections immer global deklariert werden müssen, damit auch alle threads blockiert werden ?!
Ist das richtig ?
Kann ich nicht innerhalb meines Threads als private Var eine CS erzeugen ? Ich schütze ja auch nur das add und Delete der ebenfalls internen stringliste. Und der Zugriff geschieht ja nicht direkt von anderen Threads sondern wie oben beschrieben mit der Add-Methode des Threads.

Letze und abschliessende Frage :

Ist der Construkt im obringen OnExecute praktikabel, um eine Liste in einem Thread abzuarbeiten und wenn nichts zur verarbeitung da ist, soll der Thread schlafen, wenn was hinzugefügt wird soll er aufwachen.

Danke,

Data
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#2

Re: CriticalSection nötig ?

  Alt 10. Dez 2003, 01:01
Zitat von DataCool:
kurz ne Frage zur CriticalSection:
Auch nur ne kurze Antwort, will langsam ins Bett

Zitat:
Da TStringList ja nicht Thread sicher ist, muss ich hier mit CriticalSection arbeiten ?
ja

Zitat:
Obwohl ich von aussen nur immer Elemente am ende der liste hinzufüge ?
obwohl Du "von außen" arbeitest. Was ändert der schlichte Aufruf der Methode?

Zitat:
Wenn ich mit CriticalSection arbeite, dann nur bei Delete der stringliste oder auch beim Add ?
Auch bei Add.

Zitat:
Irgentwo hab ich mal gelesen das CriticalSections immer global deklariert werden müssen [...]?! Ist das richtig ?
Nein.

Zitat:
Kann ich nicht innerhalb meines Threads als private Var eine CS erzeugen?
Geeignete Lösung und performanter als alle Listen über ein gemeinsames Synchronisationsobjekt zu steuern.

Zitat:
Ist der Construkt im obringen OnExecute praktikabel?
Ideal wäre ein FiFo-Puffer, der den Thread (caller von Pop) solange schlafen legt (ich auch gleich ) bis wieder ein neues Element dem Puffer zugefügt worden ist (Push).
Schau mal unter in der OH unter Semaphore und Signal im Zusammenhang von Synchronisationsobjekten nach. Das Szenario, was Du beschreibst, nennt man iÜ Bei Google suchenthread producer consumer.
gruß, choose
  Mit Zitat antworten Zitat
Rumpi

Registriert seit: 26. Aug 2003
Ort: Berlin
72 Beiträge
 
#3

Re: CriticalSection nötig ?

  Alt 10. Dez 2003, 07:40
Hi,

ich arbeite dann immer mit TThreadList.
Das ist der sicherste Weg.

Delphi-Quellcode:
  with AThreadList.LockList do // -> TList Thread save
  try



  finally
    AThreadList.UnLock;
  end;
mfg Rumpi No.5
  Mit Zitat antworten Zitat
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#4

Re: CriticalSection nötig ?

  Alt 10. Dez 2003, 08:07
Zitat von Rumpi:
Das ist der sicherste Weg.
Leider nicht, selbst wenn die Datenklasse (ob nun in Form eines FiFo-Puffers oder einer Liste) selbst den kritischen Bereich vor gegenseitigem Ausschluss schützt, können immernoch Verklemmungen (Deadlocks) auftreten, sofern die Operationen nicht atomar sind (hold and wait), also gegenseitige Abhängigkeiten existieren und keine Ordnung (zB in Form einer Hierarchie) vorliegt...

Das Thema Threads hat mehr Fallstricke als die Erzeugung von, Warten auf und Benachrichtigung zwischen ihnen!
gruß, choose
  Mit Zitat antworten Zitat
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#5

Re: CriticalSection nötig ?

  Alt 10. Dez 2003, 09:55
@Choose:

Erstmal danke für Deine Antwort, hat mir schon sehr geholfen.

Bei dem Thema Threads gibt es ja auch verdammt viel Lösungsansätze und keiner ist die Patent-Heilmethode

Ich habe Deinen Link zum Thema FiFo-Puffer etwas näher betrachtet, dazu noch eine Frage :

Ist das nicht genau das Prinzip, was ich da konstruiert habe ?

Die OnExecute-Methode legt sich schlafen, wenn nichts mehr zur Verarbeitung da ist und die Add Methode weckt den Thread wieder auf, falls er schläft.

Wo ist der Unterschied ?

Gruß Data
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#6

Re: CriticalSection nötig ?

  Alt 10. Dez 2003, 10:07
Der Unterschied leigt, wie häufig in der OOP, bei der Zuständigkeit: Den Thread hat es nicht zu interessieren, dass er "schlafen gelegt wird". Auch das Locking sollte nicht in seinen Zuständigkeitsbereich fallen.
Idealerweise ist diese Verhalten vollkommen transparent, etwa in der Form:
Delphi-Quellcode:
procedure TMyThread.Execute;
var
  myItem: TMyClass;
begin
  Assert(Assigned(FFifoData), 'FiFo-Buffer not assigned');

  while not Terminated do
  begin
    myItem:= FFifoData.Pop;
    DoSthWidth(myItem);
  end;
end;
bzw
Delphi-Quellcode:
procedure TMyTread.AddItem(const AnItem: TMyClass);
begin
  if not Assigned(AnItem) then
    raise EItemNotAssignedError.Create(ItemNotAssigned);

  Assert(Assigned(FFifoData), 'FiFo-Buffer not assigned');
  FFifoData.Push(AnItem);
end;
Das Blockieren eines Clients (Aufrufer), der die Nachricht Pop schickt, sowie dessen anschließende Fortsetzung, sobald ein Element dem Puffer hinzugefügt worden ist, übernimmt nach diesem Muster vollständig der Puffer.

Problematisch ist in diesem Zusammenhang lediglich der Fall, dass der Thread beendet werden soll, jedoch kein weiterer Eintrag im Puffer vorhanden ist. Hierfür könnte eine spezielle Methode des Puffers eingesetzt werden, der alle Consumer (den Thread) weckt, ohne ein Element als Rückgabewert von Pop zur Verfügung zu stellen. Denkbar ist der Wurf einer Exeception EBufferClosed, die dann in Execute adequat behandelt werden sollte:
Delphi-Quellcode:
procedure TMyThread.Execute;
var
  myItem: TMyClass;
begin
  while not Terminated do
  try
    myItem:= FFifoData.Pop;
    DoSthWidth(myItem);
  except
    on EBufferClosed do
      Terminate;
  end;
end;
gruß, choose
  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:07 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