Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi "Grundsatzfrage" zur Thread-Programmierung (https://www.delphipraxis.net/120895-grundsatzfrage-zur-thread-programmierung.html)

Errraddicator 18. Sep 2008 14:28


"Grundsatzfrage" zur Thread-Programmierung
 
Hiho,

hab da mal ne grundlegende Frage, die ich eigentlich nich im Detail sondern eher grob beantwortet haben möchte, da ich damit erst demnächst anfangen kann, wollte mich nur im Vorfeld schon ma etwas schlau machen, worauf ich so zu achten hab.

Bisher laufen meine Programm meist nach folgendem Schema ab:
- Form wird gestartet
- Benutzer tätigt Eingaben
- Benutzer startet per Button die Verarbeitung bestehend aus Prozeduren und/oder Funktionen innerhalb des Formulars geschieht
- Benutzer schließt das Programm

Also ne stinknormale Windows-Anwendung im klassischen Sinne halt.

...

Jetzt habe ich vor folgendes zu machen:
- Form wird gestartet
- Benutzer tätigt Eingaben
- Benutzer startet per die Verarbeitung bestehend aus 3 Threads.
1 Thread zum Lesen der Daten aus der Datenbank und wandeln in Datenstrukturen
1 Thread zum verarbeiten der Datenstrukturen
1 Thread zum schreiben der verarbeiteten Daten in eine Ausgabedatei
- Benutzer schließt das Programm

Sprich: Ich möchte die Verarbeitung von 1 auf 3 Threads aufteilen, um die CPU-Nutzung zu erhöhen und die Laufzeit zu verbessern.

...

Meine Frage bezieht sich jetzt auf die Interaktion zwischen den Freds
Ich habe mir das in etwa so vorgestellt:
Thread 1: Liest Daten aus Datenbank, wandelt und gruppiert diese in brauchbare Datenstrukturen
und stellt jede Datenstruktur sobald sie fertig ist in eine TList z.B.

Thread 2: Überprüft diese TList stetig auf bereit gestellte Daten,
verarbeitet den Datensatz und stellt diesen in eine zweite TList.

Thread 3: Überprüft die zweite TList auf bereit gestellte Daten,
und gibt die Datensätze aus.

...

Schematisch dargestellt
Thread1 (Liest Daten...)
|
v
TList 1
^
|
Thread 2 (Verarbeitet Daten...)
|
v
TList 2
^
|
Thread 3 (Gibt Daten aus...)

...

Ist das so machbar oder gibt es dann Probleme mit dem gleichzeitigen Zugriff auf die TListen z.B.?
Bzw. wer hat sowas schon gemacht / macht sowas und könnte mir sagen worauf man da als mehr oder weniger Threadunerfahrener Mensch achten muss?


Danke im Voraus

cu Patrick

Luckie 18. Sep 2008 15:16

Re: "Grundsatzfrage" zur Thread-Programmierung
 
Ist so machbar, du musst nur darauf achten, dass nicht gleichzeitig lesen und schreibend auf die Liste zugegriffen wird.

MrKnogge 18. Sep 2008 15:21

Re: "Grundsatzfrage" zur Thread-Programmierung
 
Zitat:

Zitat von Luckie
[...] nicht gleichzeitig lesen und schreibend auf die Liste zugegriffen wird.

Wäre es daher nicht besser lesen/schreiben in einen Thread zu packen?

jfheins 18. Sep 2008 19:25

Re: "Grundsatzfrage" zur Thread-Programmierung
 
Sollte so gehen, aber ich würde das noch etwas verändern.

Um das ganze besser zu trennen und zu vereinfachen, würde ich folgende Striktur vorschlagen:

1. Die ganze Arbeit ist in einer Klasse gekapselt.
Beispielsweise mit 3 Methoden Lesen(), Verarbeiten() und schreiben()

Am Anfang alle 3 Thread erstellen mit Suspended = true; und 4 Objektlists erstellen.

MainThread erstellt 1 Objekt mit den Anfangsdaten. Tut das dann in eine Liste rein und wirft den ersaten Thread an. Der schaut dann in diese Lste rein und nimmt das Objekt da raus (sysnchronisiert). (So kann vom Hauptthread auch nicht mehr darauf zugegriffen werden)
Thread 1 ruft jetzt Objekt.Lesen() auf - welches daraufhin ja im Thread abläuft. Danach kann das Objekt (synchronisiert) in der zweiten Liste abgelegt werden und Thread 2 angeworfen werden.
Jetzt schaut der Thread 1 wieder nach Daten, wenn keine mehr da sind, legt er sich schlafen, sonst fängt er von vorne an.
Währenddessen fängt Thread 2 an, zu arbeiten, und entfernt das Objet aus Liste 2, rift Objekt.Verarbeiten() auf und so weiter ;)

Am Ende landen die Verarbeiteten Objekte dann (von Thread 3) in Liste 4 und du kannst damit wieder machen, was du willst.

Blup 19. Sep 2008 16:38

Re: "Grundsatzfrage" zur Thread-Programmierung
 
Zitat:

Zitat von Errraddicator
Sprich: Ich möchte die Verarbeitung von 1 auf 3 Threads aufteilen, um die CPU-Nutzung zu erhöhen und die Laufzeit zu verbessern.

Die CPU-Nutzung zu erhöhen kann nur ein Mittel sein um die Laufzeit zu verringern. Es stellt sich nur die Frage ob das in diesem Fall der richtige Weg ist.
Ich habe die Erfahrung gemacht das oft schon kleine Eingriffe in den Ablauf eine dramatische Veränderung der Laufzeit bringen.
Da Threads das Programm deutlich verkomplizieren können, sind sie für diesen Zweck eher das letzte Mittel.

Unabhängig davon halte ich es für sinnvoller wenn ein Thread die Verantwortung für jeweils ein Datenobjekt übernimmt. Das heist er führt für dieses Datenobjekt nacheinander alle Aufgaben vom Lesen über Verarbeiten bis zur Ausgabe durch. Sind die Aufgaben für ein DatenObjekt erledigt, so kann man diesem Thread ein neues DatenObjekt übergeben oder beenden. Entsprechend den verfügbaren Ressourcen kann das Programm zur Laufzeit die Anzahl der Threads steuern.

Errraddicator 22. Sep 2008 08:18

Re: "Grundsatzfrage" zur Thread-Programmierung
 
Zitat:

Zitat von Blup
Die CPU-Nutzung zu erhöhen kann nur ein Mittel sein um die Laufzeit zu verringern. Es stellt sich nur die Frage ob das in diesem Fall der richtige Weg ist.
Ich habe die Erfahrung gemacht das oft schon kleine Eingriffe in den Ablauf eine dramatische Veränderung der Laufzeit bringen.

Das Problem sind bei meinen Anwendungen hauptsächlich die Datenbankzugriffe.
Und da ich im Regelfall auf eine objektorientierte und keine relationelle Datenbank zugreife (über eine mitgelieferte Schnittstelle des Software-Herstellers) sehe ich da auch ehrlich gesagt keine großartige Möglichkeit, das zu beschleunigen.
Denn wenn der Datenzugriff dort nun ma so und so lange dauert, bis ich was auslesen kann, dann dauert das halt so lange.

Von daher muss ich ja drumherum arbeiten / meine Programme so gestalten, dass ich diesen Flaschenhals so weit wie möglich umgehe, denn den Flaschenhals an sich kann ich ja nich beeinflussen.

Blup 22. Sep 2008 16:18

Re: "Grundsatzfrage" zur Thread-Programmierung
 
In dem Fall bringt die Aufteilung auf mehrere Threads vermutlich keine Verbesserung der Gesamtlaufzeit (es sei den die Schnittstelle ist Multithreadfähig).
Ich würde neben dem Hauptthread, der mit dem Benutzer interagiert, nur einen zweiten Thread anlegen, der im Hintergrund die Arbeit erledigt.

Errraddicator 23. Sep 2008 07:06

Re: "Grundsatzfrage" zur Thread-Programmierung
 
Ist natürlich gut möglich, dass das keine relevanten Vorteile bringen wird, aber zumindest versucht will ich es mal haben. :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:58 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