AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi Lesen einer außerhalb des Threads verwalteten Liste

Lesen einer außerhalb des Threads verwalteten Liste

Ein Thema von Der schöne Günther · begonnen am 20. Mär 2013 · letzter Beitrag vom 21. Mär 2013
Antwort Antwort
Der schöne Günther

Registriert seit: 6. Mär 2013
6.173 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

Lesen einer außerhalb des Threads verwalteten Liste

  Alt 20. Mär 2013, 12:54
Situation:

Delphi-Quellcode:
TKlasse = class
   protected type meinThread = class(TThread)
      [...]
   end;
   private var kritischerAbschnitt: TCriticalSection;
   
   public var meineListe:TList<TDatensatz>;

   [...]
end;
TKlasse hat einen TThread der öfter mal einen neuen TDatensatz an die Liste meineListe anhängt. Würde dieses Anhängen die Liste größer als ein bestimmtes Maximum werden lassen, wird der älteste Datensatz herausgeworfen.

Nun möchte ich allerdings auch im Hauptthread unkompliziert schauen, wieviele Datensätze ich schon habe, einen auswählen und auch grafisch darstellen. Problem: Niemand garantiert mir, dass ein ausgewählter Datensatz in der nächsten Zeitscheibe nicht schon durch den Nebenthread entfernt wurde!

Als Lösung fällt mir nur ein, den kritischen Abschnitt (an den sich natürlich beide Threads halten müssen) voll public zu machen um ihn dann auch im Hauptthread zu benutzen:
- Abschnitt betreten
- TDatensatz in der Liste finden
- Grafisch darstellen
- Abschnitt verlassen

Aber ganz ehrlich - Bei jedem möglichen Zugriff mit dem kritischen Abschnitt zu jonglieren ist doch einfach nur hässlich und fehleranfällig. Ich würde lieber einen Abend an der Stange tanzen gehen als den Zugriff auf "meinen" kritischen Abschnitt public nach außen zu führen.

Sind meine Bedenken unbegründet? Oder habe ich eine bessere Methode übersehen?
  Mit Zitat antworten Zitat
taveuni

Registriert seit: 3. Apr 2007
Ort: Zürich
534 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Lesen einer außerhalb des Threads verwalteten Liste

  Alt 20. Mär 2013, 13:13
Dann mach aus var meineListe ein property.
Und im Getter gibts Du Liste innerhalb der CritcalSection zurück.
Somit braucht der Hauptthread nichts von einer Criticalsection zu wissen.
Die obige Aussage repräsentiert meine persönliche Meinung.
Diese erhebt keinen Anspruch auf Objektivität oder Richtigkeit.
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.173 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Lesen einer außerhalb des Threads verwalteten Liste

  Alt 20. Mär 2013, 13:21
Richtig.

Aber das ändert nichts daran, dass
  • Liste holen
  • Durch Elelemte der Liste wandern
  • Element finden
  • Dinge mit dem Element tun
atomar ablaufen müssen.

Sonst passiert bsp. das hier:
  • Ich finde mein Element
  • Ich tue Dinge damit
  • Ich werde "unterbrochen" vom Nebenthread
  • Nebenthread entfernt das Element aus der Liste...
  • ... und ruft den Destruktor des Elements auf
  • will weiter Dinge tun
  Mit Zitat antworten Zitat
taveuni

Registriert seit: 3. Apr 2007
Ort: Zürich
534 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Lesen einer außerhalb des Threads verwalteten Liste

  Alt 20. Mär 2013, 13:23
Absolut korrekt. Das muss immer so sein wenn unterschiedliche Threads eine Liste lesen/schreiben.
Nur kannst Du die atomare Absicherung privat in der Klasse vornehmen.
Die obige Aussage repräsentiert meine persönliche Meinung.
Diese erhebt keinen Anspruch auf Objektivität oder Richtigkeit.
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#5

AW: Lesen einer außerhalb des Threads verwalteten Liste

  Alt 20. Mär 2013, 23:34
Das alte Lied: Parallele Systeme sind schwer zu programmieren


- Abschnitt betreten
- TDatensatz in der Liste finden
- Grafisch darstellen
- Abschnitt verlassen
Enthält der Datensatz Referenzen oder ist besonders groß? Wenn nicht, würde ich eine andere Vorgehensweise vorschlagen:
  • Abschnitt betreten
  • TDatensatz in der Liste finden
  • Abschnitt verlassen
  • Grafisch darstellen
Kritische Abschnitte sollten so klein wie möglich sein. Das Zeichnen dauert vermutlich sogar länger als eine typische Listenoperation.

Dies ließe sich noch verbessern:
Code:
datensatz = tKlassenObjekt.findeDatensatz(...);
stelleDar(datensatz);
Die CriticalSection und die Liste bleiben dabei privat und alles ist schön gekapselt.

Schöner wäre noch, wenn du für die Liste eine Klasse schreibst, die solche Funktionen wie findeDatensatz und einfuegeDatensatz threadsicher bereitstellt. Das sorgt dann dafür, dass du dich im Hauptthread sowie im andere Thread nicht mehr um die Threadsicherheit kümmern musst.

Wenn die Datensätze zu groß oder zu kompliziert zum Kopieren sind, dann könntest du mit Referenzzählung arbeiten.
Das sollte natürlich auch alles threadsafe und deadlockfrei passieren
Intellekt ist das Verstehen von Wissen. Verstehen ist der wahre Pfad zu Einsicht. Einsicht ist der Schlüssel zu allem.

Geändert von BUG (20. Mär 2013 um 23:44 Uhr)
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.173 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: Lesen einer außerhalb des Threads verwalteten Liste

  Alt 21. Mär 2013, 08:15
Das alte Lied: Parallele Systeme sind schwer zu programmieren
Ja ich merke auch langsam, dass ich nicht der erste Mensch auf Erden bin, der sich damit herumärgert

Enthält der Datensatz Referenzen oder ist besonders groß?
Das steht noch nicht ganz fest, möglicherweise wird er alles andere als klein weshalb ich bislang davon ausgegangen bin, dass das Zeichnen sogar schneller als ein Kopiervorgang über die Bühne geht. Aber wahrscheinlich liege ich damit falsch.

Schöner wäre noch, wenn du für die Liste eine Klasse schreibst, die solche Funktionen wie findeDatensatz und einfuegeDatensatz threadsicher bereitstellt. Das sorgt dann dafür, dass du dich im Hauptthread sowie im andere Thread nicht mehr um die Threadsicherheit kümmern musst.
Das wäre die beste aller Welten. Nur wird es am Ende wahrscheinlich wieder auf ein Dutzend verschiedene Kriterien, einen Datensatz zu "finden" hinauslaufen, was dann wieder auf eine Menge Methoden hinausläuft...


Vielen Dank für die Antworten bislang!
  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
 
#7

AW: Lesen einer außerhalb des Threads verwalteten Liste

  Alt 21. Mär 2013, 08:37
Du solltest den Thread wie einen Freund behandeln.

Du gibst diesem Freund ein paar Äpfel zum Essen.

Es ist unhöflich bei jedem Passanten, der vorbeikommt, dem Freund die Äpfel aus den Händen zu reißen, nur um diesem Passanten die Äpfel zu zeigen.

Frage den Freund, dass er dir die Äpfel zeigen soll (er wird beim Essen unterbrochen), oder vereinbare mit ihm, dass er dir Rückmeldungen geben soll, welchen Apfel er gerade isst, wie viel er von dem Apfel schon gegessen hat und wenn der Apfel gegessen ist (er kann fast kontinuierlich essen).

Thread-Programmierung hat also auch etwas mit Höflichkeit zu tun
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)
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.173 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

AW: Lesen einer außerhalb des Threads verwalteten Liste

  Alt 21. Mär 2013, 09:27
Was für eine Philosophie
Hätte man Konfizius zu Multithreading-Programmierung gefragt, er hätte wahrscheinlich genau so geantwortet!

Wahrscheinlich wird es auch darauf hinauslaufen: Ich werde dem Thread auf die Fuße treten und entweder sagen, er soll mir mitteilen, was für Äpfel er gerade in seinen Händen hält oder mir ihm sagen, er soll mir mal einen bestimmten Apfel geben. Dabei kann er ja gleich noch eine Deep Copy des Apfels machen und ich kann mit dem Apfel fortan anstellen was ich will...
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.477 Beiträge
 
Delphi 12 Athens
 
#9

AW: Lesen einer außerhalb des Threads verwalteten Liste

  Alt 21. Mär 2013, 09:37
Vieleicht bietet das "visitor pattern" hier eine Lösung.
Wenn deine "TKlasse" als besuchtes Element im "accept" den Aufruf von "visit" mit "kritischerAbschnitt" kapselt, können beliebige Aktionen im Hauptthread ausgeführt werden.
Für jede Aufgabe kann man sich eine kleine Visitorklasse erstellen.
  Mit Zitat antworten Zitat
taveuni

Registriert seit: 3. Apr 2007
Ort: Zürich
534 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: Lesen einer außerhalb des Threads verwalteten Liste

  Alt 21. Mär 2013, 09:37
[..] Dabei kann er ja gleich noch eine Deep Copy des Apfels machen [..]
Das würd ich aber nur tun wenn Du Apfelsaft damit machen willst. Den die Zeit und die Ressourcen welche für das klonen
und das freigeben verschwendet werden - müssen im Verhältnis zur Zeit der Blockade in der Critical Section berücksichtigt werden.
Die obige Aussage repräsentiert meine persönliche Meinung.
Diese erhebt keinen Anspruch auf Objektivität oder Richtigkeit.
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 14:10 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