![]() |
Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thread)
Tut mir leid für den Betreff aber mir fällt nichts ein zu meinem Problem!
Ich habe eine Klasse TThreads
Delphi-Quellcode:
In der public-Ebene habe ich eine Hand voll Variablen.
type TThreads = class
Eine davon zielt auf eine Thread-Unit (also den Thread selber). Die andere auf eine normale Klasse, kein Thread. In etwa
Delphi-Quellcode:
Im Thread TMeinThread gibt es eine Variable bThreadSleeping welche ich so ansprechen kann:
type
TThreads = class private // public itemX: TMeinThread; itemY: TIrgendeineWeitereKlasse; // ein paar wenige weitere Variablen end;
Delphi-Quellcode:
aThreadInfo ist folgendermaßen deklariert
aThreadInfo.ThreadList.Items[i].itemX.bThreadSleeping
Delphi-Quellcode:
Threads füge ich so hinzu
type
TThreadInfo = packed record ThreadList: TObjectList<TThreads>; iThreadID: Cardinal; ThreadHandle: THandle; end; aThreadInfo: TThreadInfo;
Delphi-Quellcode:
Funktioniert seit vielen Jahren einwandfrei!
aThreadInfo.ThreadList.Add(TThreads.Create(....));
Nun brauche ich bThreadSleeping aber im Thread selber und auch in itemY, also TIrgendeineWeitereKlasse. Wie komme auch aus TMeinThread und TIrgendeineWeitereKlasse an eine Variable dran, die im übergeordneten Element liegt? Also einem TThreads-Element? |
AW: Frage zu Threads generell
Wie wäre es die Variable in ein Interface auszulagern? Das kann dann der Thread genauso kennen wie die andere Klasse.
Ist das ein eigener Threadpool? Da gibt es schon so viele fertige Implementierungen, dass ich schon lange keine eigene Implementierung mehr nutze. Alleine schon was in der OmniThreadLibrary oder der mit Delphi mitgelieferten Parallel Programming Library möglich ist... |
AW: Frage zu Threads generell
Was passiert denn genau außenrum?
Du suchst jetzt aber nicht ![]() (Wenn ja: Titeländerung zu "Threadlokaler Zugriff auf Variablen"?) :idea: Vielleicht lässt sich dein Problem aber auch auf makroskopischerer Ebene umgehen? Was möchtest du denn genau tun? Bzw was ist das Ziel? :) Brighty |
AW: Frage zu Threads generell
Interfaces, nein danke :thumb:
Doch das ist mein eigener ThreadPool. Eine ObjectList mit Threads drin und jeder Thread hat noch 2 Unterklassen. Ich weiß ja eben nicht wie das heißt was ich suche. Aber die 2 Unterklassen sollten irgendwie an eine Variable im ThreadList.Items[i] selbst drankommen können. Wie soll das denn mit der Threading-Library funktionieren? |
AW: Frage zu Threads generell
Also wenn das eine 1:1 Zuordnung ist, dann kannst du vielleicht dort, wo du Zugriff auf die Klasse brauchst eine Referenz dorthin vergeben (also in dem Fall die TThreads Referenz).
Im Allgemeinen bin ich aber gegen zirkuläre Referenzen (z.B. Klasse A kennt Klasse B und Klasse B kennt Klasse A,...), weil das oft auf ein generelleres Problem im Entwurf zeigt, das man eventuell refactoren kann (oft sind die 1:1 Objekte dann semantisch sehr ähnlich und durch die zirkuläre Referenzen stark miteinander verbunden...). Daher meine Frage nach dem Entwurf :) |
AW: Frage zu Threads generell
Ich mache das Ganze sehr gerne besser. Aber ohne Interfaces denn die A) verstehe ich nicht und B) habe ich keine Lust sie jetzt schnell zu erlernen.
Also... gerne mache ich das alles komplett anders. |
AW: Frage zu Threads generell (ObjectList mit Klassen drin und jede Klasse hat 1 Thre
Was möchtest du denn tun? Bzw was ist dein Ziel?
Ich versuche noch immer zu verstehen, was genau dein Problem ist. :) (totally unrelated zu Interfaces: Ich glaube, dass du grundsätzlich das Prinzip von Interfaces schon verstanden hast, wenn du ein bisschen Objektorientierung verwendet hast; Interfaces sind nichts anderes als Klassen ohne Implementierung. Habe keine Angst davor! :P Der Vorteil ist nur, dass du manchmal flexibler bist; Die effektive Verwendung von Interfaces führt oft einfach dazu, dass dein Modell weniger stark zusammenhängt. Ich glaube aber dein Problem sitzt in dem Fall aber wo anders...) |
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Zitat:
Lasst ihm seinen Willen :) Ist ja auch nicht weiter tragisch. gruss |
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Mein Ziel grob erklärt:
mein hat eine ListView und jede ListView ist ein Datensatz. Jeder, ich nenne es mal "Eintrag", kann einen Thread im Hintergrund laufen haben, muss aber nicht. Wenn aber ein Thread im Hintergrund für einen Eintrag laufen soll, dann wird meiner ObjectList über Add eine Instanz von TThreads übergeben. Im Create von TThreads wird der eigentliche benötigte Thread erzeugt. Über aThreadInfo.ThreadList.Items[i].itemX kann ich nun auf meinen Thread zugreifen. Über aThreadInfo.ThreadList.Items[i].VARIABLEXYZ auch auf Variablen der Klasseninstanz selber (nicht des Threads, der Thread ist itemX). Ich möchte nun, dass mein Thread itemX auf Variablen der Klasseninstanz zugreifen kann, dem er (der Thread) angehört. Aktuell haben bei mit itemX und itemY jeweils eine Variable, die den gleichen Zweck erfüllen. Deswegen dachte ich packe ich die in die Klasseninstanz dann habe ich nur noch eine. Beispiel: aThreadInfo.ThreadList.Items[i].itemX.bPause würde den Thread (itemX) dann pausieren (setter). Hier wäre es aber besser eine einzige Variable zu haben, die ich aus beiden Teilen, itemX und itemY, abrufen kann. Zitat:
|
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Wenn ich dich richtig verstanden habe, möchtest du innerhalb eines Threads auf ein Set von Variablen zugreifen, die für diesen Thread zur Abarbeitung seiner eigenen Tätigkeit wichtig sind. Was hindert dich daran, bei der Initialisierung des Threads diesen "Kontext", also eine Referenz auf dein übergeordnetes Objekt diesem zu übergeben? :) (also eine Referenz auf dein jeweiliges TThreads)
|
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Zitat:
Zitat:
Ehrlich gesagt habe ich da jetzt nur spontan Pointer und Const im Kopf. Aber das ist es nicht, was du ansprichst, oder? Woran ich auch gedacht habe ist, dem Thread eine ID mitzugeben (die ID des "items[i]"). Aber das würde mich sehr einschränken was Änderungen an den ObjectList-Items, also den Klasseninstanzen, angeht. |
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Du kannst deinem Thread übergeben was dir beliebt. Es ist ja dein Programm 8-)
Oder dein TMeinThread hat eben entsprechende (u.U. private) Felder, die im Construktor mit übergeben werden, auf die du dann von Execute aus Zugriff hast. Wenn die Variablen auch nur dort relevant sind, kannst du diese vielleicht auch aus TThreads dorthin verschieben und dann auch von dort darauf zugreifen? Vermute ich das richtig, dass deine Referenz itemX auf deinen Thread in TThreads nur deshalb existiert, damit du diesen noch von außen abbrechen kannst/den Status rausfinden kannst? Existieren TThreads Einträge in deiner Liste, deren itemX nil ist? Brighty |
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
itemX ist die Instanzvariable des Threads und mit aThreadInfo.ThreadList.Items[i].itemX.bPause lege ich den Thread schlafen (ich prüfe einfach auf while bPause do ... (bPause, property, Boolean steht in der Unit des Threads)
Habe gerade das hier gefunden und gucke es mir gleich mal an. ![]() Demnach kann ich dann ja ... ok muss ich gleich gucken wenn ich wieder eine IDE habe.. gucke ich gleich welches Object ich als Parameter übergeben kann. Edit. wenn ich den constructor habe
Delphi-Quellcode:
Da müsste ich dann ja die Referenz übergeben. Wäre das hier, haut mich nicht.. aber wäre das nicht "Self" (constructor)?
constructor TThreads.Create(...);
begin ... itemX := TMeinThread.Create(...); // <== HIER ... end; aThreadInfo.ThreadList.Add(TThread.Create(...)); |
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Ah. Ich wusste unser Problem liegt wo anders :thumb:
Ja, also wenn du ganz klassisch (so wie bei einem ganz normalen Funktionsaufruf, in Konstruktoren, ...) ein Objekt mit übergibst, dann ist das nur eine Referenz auf dieses Objekt. Intern übersetzt dir dein Compiler das oft einfach nur in Pointer auf das Objekt. Also genau wie indem stackoverflow Beitrag beschrieben... Dich hindert niemand daran, diese Referenz in mehreren Instanzen oder/und in mehreren Feldern zu halten. Nur aufpassen beim Free usw: Wenn du natürlich das Free auf einer dieser Referenzen aufrufst, dann werden die anderen logischerweise auch davon betroffen sein! Brighty Edit: genau. TMeinThread.Create braucht halt im Konstruktor noch entsprechend den Parameter. Was du hier aber jetzt machst ist das klassische Beispiel einer zirkulären Referenz: dein TMeinThread kennt TThreads und TThreads kennt TMeinThread. Wenn du das auflösen willst, sag bescheid; da gibt es einen kleinen Trick. |
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Ok nur um das festzuhalten:
"Self" im Konstruktor bezieht sich auf den Konstruktor/das durch den Konstruktor erzeugte Objekt selber. Und im Konstruktor itemX := TMeinThread.Create(...); aufrufen würde mir in der Thread-Instanz ItemX dann eine Referenz auf das TThread zur Verfügung stellen? |
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
TThreads; Nicht nur im Konstruktor. Innerhalb einer Methode, Funktion, Destruktor, ...
|
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Ich teste das gleich mal schnell. Sollte ja nur eine Tipparbeit von 1 Minute sein (neuer Parameter) und ein showmessage in der Thread-Unit zum Test.
|
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Die spannende Frage verbleibt: Wenn deine TThreadInfo.ThreadList nur diejenigen Einträge deiner ListView Einträge hält, die grade einen Thread benötigen; Brauchst du dann TThreads als Klasse wirklich? Oder könntest du nicht dann auch den Typ deiner ThreadList einfach auf TMeinThread ändern und einfach alle itemY, itemZ, itemQ, itemA,.... Felder in deine TMeinThread Klasse verschrieben und TThreads wegrationalisieren?
(Kenne den Rest des Programms nicht...) TMeinThread ist schließlich auch nur eine ganz stinknormale Klasse, die einfach nur von TThread erbt. Nichts besonderes also; die kann ganz normal Methoden und Felder bekommen, wenn sie mag... :) Brighty |
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Demnach könnte ich dann mein Konstrukt
Delphi-Quellcode:
entfernen. Die Variablen iThreadID und ThreadHandle benutze ich so oder so nirgendwo.
type
TThreadInfo = packed record ThreadList: TObjectList<TThreads>; iThreadID: Cardinal; ThreadHandle: THandle; end; Oder habe ich etwas falsch verstanden? |
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
... und aus
Delphi-Quellcode:
würde
ThreadList: TObjectList<TThreads>;
Delphi-Quellcode:
, wenn du alle anderen Felder außer itemX nach TMeinThread verschieben würdest (itemX fiele ganz weg in dem Fall).
ThreadList: TObjectList<TMeinThread>;
Wenn du soweit bist und damit zufrieden bist, könnten wir eventuell nochwas anderes ansprechen, wenn du magst :P |
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Ahh ok habs kapiert.
Das geht leider nicht. Denn es gibt ja nicht nur den Thread TMeinThread. Es gibt noch eine weitere Unit die kein Thread ist. Näheres kann ich aber erst sagen wenn ich mir später alles nochmal angucke. |
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Hält diese Unit zufälligerweise die selben Daten, wie auch der TMeinThread verarbeitet? :P:):roll:
|
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Das weiß ich gerade nicht aber es gibt ein anderes Problem.
meine erste Unit die TTheads = class und den constructor usw. enthält hat in der uses-klausel die Unit stehen die der eigentliche Thread ist. In der Thread-Unit müsste ich dann auch wieder in die uses die Unit eintragen die TThreads enthält. Das geht leider nicht (zirkulär :( ) Mein Vorhaben ist also am Ende :stupid: Ich könnte das Problem umgehen, indem ich die Thread-Unit in die andere Unit, die den Thread erzeugt, verfrachte aber das will ich ehrlich gesagt nicht. |
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Genau. Das meinte ich vorhin. Daher mein Vorschlag, das zu verschieben. Was macht denn deine andere Klasse, die kein Thread ist (aber die dich vorhin hinderte die Liste von TThreads zu TMeinThread zu ändern)? Da lässt sich sicher nochwas verschieben. :wink:
Nichts ist am Ende :) |
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Verschieben in eine Unit geht ja auch nicht.
Delphi-Quellcode:
TThreads braucht TThreads und TMeinThread braucht TThreads. Egal wie man es dreht und wendet.
type
TThreads class ... constructor Create(xyz: TMeinThread); itemX: TMeinThread; end; type TMeinThread = class(TThread) ... constructor Create(xyz: TThreads); end; Ich glaube ich bleibe einfach bei den zwei Variablen bevor ich hier jetzt alles komplett auseinander nehme. |
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Wie du meinst, aber warum kannst du die nicht in eine Klasse verschieben? :shock:
|
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Siehe hier
Delphi-Quellcode:
TThreads-constructor braucht TMeinThread, was unten drunter steht (geht nicht)
type
TThreads = class ... constructor Create(xyz: TMeinThread); itemX: TMeinThread; itemY: ....; end; type TMeinThread = class(TThread) ... constructor Create(xyz: TThreads); end; TMeinThread-contructor braucht TThreads, was oben drüber steht (das geht). Und egal wie ich es wende, irgendeine der beiden Klassen braucht immer irgendwas was nicht zur Verfügung steht. Ich könnte ja auch, wie du sagtest, TThread wegmachen und nur TMeinThread in der ObjectList verwenden aber dann habe ich echte Threads rumliegen die man ggf. gar nicht braucht. Weil nicht jeder ListView-Eintrag braucht einen Thread (itemX). Manche brauchen auch nur ein itemY, was kein Thread ist. Edit habe gerade nachgeguckt. itemY ist auch ein Thread aber in keinster Weise wie der von itemX. Ich könnte irgendwie beide Thread-Units zu einer verschmelzen und dann im Konstruktor bestimmen, welcher Code in der Execute-Methode ausgeführt wird aber mhh.. |
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Stelle dir vor, du hättest ein TData Objekt. Nur mal so als Gedankenspiel...
Dieses TData könnte die Daten halten, die du für deine ListView brauchst. Stelle dir vor, dass manche TData Instanzen in Wahrheit einfach vom Typ TMeinThread sind. Andere Instanzen (die, die keinen Thread brauchen) von TData sind in Wahrheit von einem anderen Typ. Stelle dir vor das ginge. Würde dir das helfen? Edit: Du könntest auch beide Threads von der selben Basisklasse erben lassen und dann in der Liste einfach deinen Basisklassentyp setzen. Die beiden Kindthreadklassen dieser Basisklasse haben dann einfach unterschiedliche Execute Implementierungen. Konkret: TMeinBasisThread erbt von TThread, TMeinXThread erbt von TMeinBasisThread, TMeinYThread erbt von TMeinBasisThread; ThreadList enthält Typen von TMeinBasisThread und TMeinBasisThread enthält alle wichtigen Felder, die du für die ListView brauchst. |
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Entweder ist es spät, oder ich bin einfach nur dumm. Denn verstanden habe ich kein bisschen :cry:
Ich lasse einfach erstmal alles so wie es ist. |
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Ich tippe auf zu spät. Wenn du magst, können wir das gerne vertagen. Ich würde da noch nicht aufgeben an deiner Stelle. Geduld zahlt sich aus 8-)
Schlaf gut! :P:thumb: Brighty |
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Perfekt wäre natürlich eine Lösung wie die deine. Aber da muss ich erstmal gesund (aktuell krank) und ausgeschlafen durchblicken.
Bis später und danke für die Hilfe soweit :thumb: So. Edit. Was ich mit meiner Idee gestern vermeiden wollte, war etwas sowas hier
Delphi-Quellcode:
Wenn bThreadSleeping nun in itemX (ein Thread) und itemY (ein anderer Thread) verfügbar wäre, könne ich an vielen Stellen Code sparen.
if aThreadInfo.ThreadList.Items[iThreadID].iMode < 5 then
bPaused := aThreadInfo.ThreadList.Items[iThreadID].itemX.bThreadSleeping else bPaused := aThreadInfo.ThreadList.Items[iThreadID].itemY.bThreadSleeping; |
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
emm ich versuche mich mal an einer Antwort...
Zitat:
Delphi-Quellcode:
geschrieben hast...
While Pause do;
So etwas macht man ![]() Du solltest Dir mal ![]() Zitat:
Zitat:
Zitat:
Zitat:
|
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Zitat:
Ohne das while im Thread kann der Thread doch gar nicht wissen, wie lange er schlafen soll. Denn ich habe auch Threads wo im Thread selber schnell ausgerechnet wird, wie lange er schlafen soll. Wie soll das denn sonst gehen? Zitat:
|
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Zitat:
![]() Zitat:
|
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Das mit dem Event ist ja schön und funktioniert super (auch weniger Code).
Aber ich kann da ja nicht sowas machen...
Delphi-Quellcode:
Aber grundsätzlich:
for i := 0 to iTimeOut do
begin MacheWasMitI; PruefeIrgendwasAnderes; PruefeNochWas; if IrgendwasErfuellt then Break; end; warum kein Sleep oder While im Thread? |
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Zitat:
Schau dir mal die CPU load an. |
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Zitat:
CPU-Auslastung: 0%. Zitat:
|
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Wenn Du mal den richtigen Code zeigst - schau ich mal drüber!
|
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Es läuft so ab:
- 1) Thread wird gestartet - 2) Execute-Methode wird ausgeführt - 3) es wird ausgerechnet, wie lange geschlafen werden soll. Das Ergebnis steht in iSleep. - 4) es folgt eine for-Schleife mit immer einem Sleep(1000); drin. Selbstverständlich auch Abbruchbedingungen usw., damit das Programm nicht hängt - 5) Ist die Schleife vorbei, wird der eigentliche Code ausgeführt Es geht also nur um Punkt 4. Eine ganz normale For-Schleife. Klar, ich habe auch andere Threads mit einer While-Schleife, aber denselben Abbruchbedingungen. |
AW: Frage zu Threads (ObjectList mit Klassen, jede Klasse hat Variablen + ggf. 1 Thre
Und warum eine For-Schleife mit N Sleeps?
Anstatt :
Delphi-Quellcode:
Kostet ~ 0 CPU Zeit... Und der Thread arbeitet wieder in wenigen Pico-Sekunden bei einem E_Event.SetEvent;
E_Event.WaitFor(FSleepTime);
Mavarik |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:41 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-2025 by Thomas Breitkreuz