![]() |
Lesen einer außerhalb des Threads verwalteten Liste
Situation:
Delphi-Quellcode:
TKlasse = class
protected type meinThread = class(TThread) [...] end; private var kritischerAbschnitt: TCriticalSection; public var meineListe:TList<TDatensatz>; [...] end;
Delphi-Quellcode:
hat einen
TKlasse
Delphi-Quellcode:
der öfter mal einen neuen
TThread
Delphi-Quellcode:
an die Liste
TDatensatz
Delphi-Quellcode:
anhängt. Würde dieses Anhängen die Liste größer als ein bestimmtes Maximum werden lassen, wird der älteste Datensatz herausgeworfen.
meineListe
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. :oops: Sind meine Bedenken unbegründet? Oder habe ich eine bessere Methode übersehen? |
AW: Lesen einer außerhalb des Threads verwalteten Liste
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. |
AW: Lesen einer außerhalb des Threads verwalteten Liste
Richtig.
Aber das ändert nichts daran, dass
Sonst passiert bsp. das hier:
|
AW: Lesen einer außerhalb des Threads verwalteten Liste
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. |
AW: Lesen einer außerhalb des Threads verwalteten Liste
Das alte Lied: Parallele Systeme sind schwer zu programmieren :wink:
Zitat:
Dies ließe sich noch verbessern:
Code:
Die CriticalSection und die Liste bleiben dabei privat und alles ist schön gekapselt.
datensatz = tKlassenObjekt.findeDatensatz(...);
stelleDar(datensatz); 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 :mrgreen: |
AW: Lesen einer außerhalb des Threads verwalteten Liste
Zitat:
Zitat:
Zitat:
Vielen Dank für die Antworten bislang!:thumb: |
AW: Lesen einer außerhalb des Threads verwalteten Liste
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 ;) |
AW: Lesen einer außerhalb des Threads verwalteten Liste
Was für eine Philosophie :-D
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... |
AW: Lesen einer außerhalb des Threads verwalteten Liste
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. |
AW: Lesen einer außerhalb des Threads verwalteten Liste
Zitat:
und das freigeben verschwendet werden - müssen im Verhältnis zur Zeit der Blockade in der Critical Section berücksichtigt werden. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:01 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