AGB  ·  Datenschutz  ·  Impressum  







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

2 Threads starten/pausieren...

Ein Thema von MicMic · begonnen am 17. Jun 2018 · letzter Beitrag vom 22. Jun 2018
Antwort Antwort
Seite 2 von 2     12   
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.332 Beiträge
 
Delphi 11 Alexandria
 
#11

AW: 2 Threads starten/pausieren...

  Alt 18. Jun 2018, 10:57
Den 0-5000 Thread erstelle in meinem OnCreate von der Form und setzte "Thread1.FreeOnTerminate := true;".
"Thread1.Start" kommt an einer anderen Stelle zum Einsatz.
Wenn du FreeOnTerminate setzt, darfst du den TThread nicht in eine Variable (Thread1) speichern. Denn da du nicht weißt wann dieser freigegeben wird, darfst du auch nicht mehr darauf zugreifen.

Wenn du den Thread später noch ansprechen möchtest, darfst du FreeOnTerminate nicht setzen.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
MicMic

Registriert seit: 26. Mai 2018
296 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#12

AW: 2 Threads starten/pausieren...

  Alt 18. Jun 2018, 11:09
Den 0-5000 Thread erstelle in meinem OnCreate von der Form und setzte "Thread1.FreeOnTerminate := true;".
"Thread1.Start" kommt an einer anderen Stelle zum Einsatz.
Wenn du FreeOnTerminate setzt, darfst du den TThread nicht in eine Variable (Thread1) speichern. Denn da du nicht weißt wann dieser freigegeben wird, darfst du auch nicht mehr darauf zugreifen.

Wenn du den Thread später noch ansprechen möchtest, darfst du FreeOnTerminate nicht setzen.
Meinst du, ich darf nicht mit "If Thread1.Terminated = False Then" prüfen, ob der noch läuft? Ich könnte ja eine Globale Variable setzen wenn der Thread1 fertig ist, also die Repeat/Until Schleife fertig ist. (Thread1fertig=true). So wäre es besser oder?
  Mit Zitat antworten Zitat
sko1

Registriert seit: 27. Jan 2017
577 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#13

AW: 2 Threads starten/pausieren...

  Alt 19. Jun 2018, 07:51
Zitat:
Wenn der zweite Thread gestartet wird, soll sich der erste Thread kurz schlafen legen, also die For-Schleife soll auch pause machen
Ich verstehe diesen Ansatz nicht ganz, das widerspricht doch dem Sinn eines Threads!
Denn der läuft im Hintergrund und blockiert damit den Haupt-Thread nicht mehr mit zeitaufwändigen Schleifen.
Warum soll der nun pausiert werden wenn ein weiterer Thread gestartet wird?

Ciao
Stefan
  Mit Zitat antworten Zitat
OlafSt

Registriert seit: 2. Mär 2007
Ort: Hamburg
284 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#14

AW: 2 Threads starten/pausieren...

  Alt 19. Jun 2018, 08:17
Warum so kompliziert.

Gib doch den einzelnen Datenelementen ein Flag "Hab ich schon" mit. Das wird gesetzt, sobald der Thread das Element verarbeitet hat. Außerdem gibst dem Thread mit, von wo bis wo er arbeiten soll (Standard 0 bis Ende). Dann lass den Thread laufen.

Will der User nun plötzlich die Elemente 200-800 verarbeitet haben, gibst dem Thread einfach diese beiden Werte an. Der Thread verarbeitet den laufenden datensatz noch ab und kümmert sich dann um die vorgegebene Range. Durch das markieren mit "Hab ich schon" werden die ja auch kein zweites Mal angefaßt. Hat der Thread seine Range durch (also 200-800 abgearbeitet), gehts einfach wieder von vorn los mit 0-Ende. Durch das "Hab ich schon" arbeitet er dann von ganz allein die ganze Arie ab - selbst wenn der User plötzlich noch 1000-1600 sehen will.

Alles in einem Thread, ohne kompliziertes Anhalten/Weiterlaufen/Synchronisieren.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.332 Beiträge
 
Delphi 11 Alexandria
 
#15

AW: 2 Threads starten/pausieren...

  Alt 19. Jun 2018, 12:24
Gib doch den einzelnen Datenelementen ein Flag "Hab ich schon" mit.
Das ist ja genau die Idee hinter der von mir vorgeschlagenen Queue, nur dass man damit die abzuarbeitenden Daten besser steuern kann als mit ein paar Flags.

Es kommt natürlich immer darauf an was man genau braucht, das kann man von außen nicht genau sagen.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Dennis07

Registriert seit: 19. Sep 2011
Ort: Deutschland
481 Beiträge
 
Delphi 11 Alexandria
 
#16

AW: 2 Threads starten/pausieren...

  Alt 19. Jun 2018, 12:27
Wenn du FreeOnTerminate setzt, darfst du den TThread nicht in eine Variable (Thread1) speichern. Denn da du nicht weißt wann dieser freigegeben wird, darfst du auch nicht mehr darauf zugreifen.

Wenn du den Thread später noch ansprechen möchtest, darfst du FreeOnTerminate nicht setzen.
Wiebitte? Wie soll er denn bitte erzeugen, FreeOnTerminate setzen und starten, ohne den Thread zwischenzuspeichern? Das ginge, wenn überhaupt, nur noch entweder im Execute (was unsauber wäre) oder mit einem with (ebenso). Prinzipiell kannst du ihn ja in so vielen Variablen speichern, wie du lustig bist. Du darfst/solltest nur nach dem Starten der Ausführung nicht mehr auf mehr auf das Objekt ohne try zugreifen, sofern FreeOnTerminate gesetzt wurde. Davor jedoch kannst du so viel an dem Ding rumspielen wie es dir danach verlangt.
Dennis
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.114 Beiträge
 
Delphi 12 Athens
 
#17

AW: 2 Threads starten/pausieren...

  Alt 19. Jun 2018, 13:23
Sorry, aber TRY ...

Man darf NIEMALS wieder darauf zugreifen, sobald der Thread einmal gestartet wurde, egal wo.

Ausnahme: Der Thread setzt diese Variable auf NIL, bevor er freigegeben wird.
Zugriffe auf diese Variable aber auch nur noch abgesichert, also z.B. innerhalb einer CriticalSection.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.332 Beiträge
 
Delphi 11 Alexandria
 
#18

AW: 2 Threads starten/pausieren...

  Alt 19. Jun 2018, 13:52
Wiebitte? Wie soll er denn bitte erzeugen, FreeOnTerminate setzen und starten, ohne den Thread zwischenzuspeichern?
Warum sollte man denn einen solchen run-and-forget Thread suspended erzeugen?!? Der bekommt alle notwendigen Parameter und legt sofort los.

(Ich sehe generell keinen Sinn darin suspended zu erzeugen, egal was für ein Thread das ist. Entweder man braucht den Thread jetzt, dann kann er auch gleich loslegen oder man braucht ihn noch nicht, dann braucht man ihn auch noch nicht erzeugen.)

Aber für genau diesen Zweck, ihn nach dem Erzeugen zu starten, kann man eine solche Variable natürlich benutzen. Aber eben danach nicht mehr.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
MicMic

Registriert seit: 26. Mai 2018
296 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#19

AW: 2 Threads starten/pausieren...

  Alt 22. Jun 2018, 00:17
Hallo,
da sind wir wohl etwas durcheinander gekommen. Oder ich
Also ich habe einen Thread der mit einer Repeat/Until-Schleife eine reihe von Zahlen durchgeht. Beispielsweise 0-5000. Den erstelle ich inaktiv in meinem Form-Create und mit „FreeOnTerminate = True“ (damit er sich selbst freigibt, wenn fertig). Inzwischen sind es zwei Threads davon, weil es auch zwei Datenhälften gibt, die wechselnd verarbeiten werden sollen. Passt so besser. Die beiden Threads nenne ich jetzt mal die Hauptthreads. Sie werden an einer passenden Stelle im Programm gestartet und kommen auch nur 1x zum starten.

Nun greift beispielsweise der Benutzer während die beiden Hauptthreads laufen ein und es wird dann von einer Datenhälfte ein Paket benötigt. (z.b. 3000-4000). Damit alles schneller geht, sollen nun die beiden Hauptthreads Pause machen.

Ich habe das nun so gelöst, dass es wiederum zwei weitere Threads gibt, die für die Aktion des Benutzers zuständig ist. Die nenne ich jetzt mal UserThreads. Die sind jedenfalls noch nicht erstellt, sondern werden erst erstellt, wenn der Benutzer die Aktion wählt, sprich das Paket von 3000-4000 als erstes geladen werden soll. Passiert so etwas, dann wird erst mal geprüft ob der Hauptthread für die richtige Datenhälfte überhaupt noch läuft. Ist er nämlich fertig, dann brauch man auch kein Userthread mehr. Diese Prüfung hatte ich mit einem „if .Terminated“ geprüft aber da war ich mir nicht so sicher, da diese Hauptthreads sich selber freigeben und ob man dann mit diesem „Termitated“ darauf noch zugreifen darf, ist mir nicht so ganz klar. Es geht zwar aber ich habe lieber eine globale Variable dafür eingesetzt. Die Benutzer-Aktion (1 von 2) schaut jedenfalls so aus:
Code:
If HThread1Finish = False Then
Begin
  UserThread1.free;
  UserThread1 := TUserThread1.Create(true);
  UserThread1.FreeOnTerminate := false;
  Userthread1.Priority := tpTimeCritical;
  UserThread1.iv := startzahl // z.B. 3000
  UserThread1.ib := enddzahl // z.B. 4000
  UserThread1.Start;
End;
Also beim ersten Mal ist ein „.free“ irgendwie nutzlos aber für weitere Aktionen ist hier dafür der beste Platz. Es macht wohl nichts aus, wenn ein Thread freigegeben werden soll, der gar nicht existiert. Bei einer 2. Aktion vom Benutzer wird er jedenfalls freigegeben und darauf wieder erstellt. So starte ich jedenfalls meine UserThreads. Hier bei den UserThreads habe ich kein „ FreeOnTerminate=True“ gewählt, da sie auch durch eine neue Aktion vom Benutzer abgebrochen werden sollen. Wegen „Priority“… ich muss da noch mal schauen ob das was bringt. In der Execute von UserThread1 (auch im anderen UserThread2) setze ich noch eine globale Varibale „ThreadsPause“ auf „True“, damit die beiden Hauptthreads nicht in der Repeat/Until Schleife weiter hoch zählen. Ist UserThread1 fertig, wird die Variable „ThreadsPause“ wieder auf „False“ gesetzt und die Hauptthreads laufen weiter bzw. sie laufen ja die ganze Zeit aber die Zählervariable dort, wird wieder weiter hochgezählt. Nach der letzten Benutzer-Aktion bleiben ja immer noch zwei UserThreads im Speicher. In meinem Form Destroy gebe ich dann noch die beiden UserThreads frei. So funktioniert das ganze eigentlich recht gut. Natürlich habe ich bei meinen Daten auch ein „hab ich schon“ also als „User[zählervariable].Nummer“ festgelegt. Die Nummer steht auf „-1“ und wenn die Daten verarbeitet wurden, wird diese auf einen anderen Wert (größer als -1) festgelegt. Also wenn der Benutzer ein Paket von 3000-4000 haben will und der Hauptthread ist hier noch nicht angekommen (wird später auf diesen Zahlenbereich kommen), dann ist dies nicht so schlimm. Ich prüfe ja auf den Wert „-1“ und nur dann kommen die rechenintensiven Befehle zum Einsatz. Das Ganze wollte ich ja nur mit einem Thread lösen aber die ganzen Variablen zu setzen (außerhalb) sind schwer im Thread zu prüfen, da der Thread ja läuft und immer wo anders ist, im Execute Bereich (mal Zeile 4, dann 7 und mal Zeile 13). Da macht es sich schwer, ein 0-5000 abzubrechen, dann 3000-4000 durchzugehen, wobei durch einen neuen Abbruch das ganze nur bis 3580 gegangen ist, weil der Benutzer ja schon wieder neue 200-1200 haben will. Dies mit Variablen so zu prüfen, dass sich nichts in die quere kommt, ist echt schwer. Bestimmt gibt es da Lösungen/Befehle etc. denn es gibt ja nicht nur „Execute“. Es sind ja auch meine ersten Erfahrungen mit Threads und so wie ich es jetzt habe, gefällt es mir natürlich dann… weils halt geht

Ich hoffe es ist nun verständlich wie ich so meine Threads einsetze und zu welchem Zweck. Ich fülle Daten Records mit Werten, die dann zur Ansicht kommen. 2-3 Befehle (um mein Daten Record zu füllen) kosten dann etwas Zeit und damit der Benutzer auf diese Ansicht nicht warten muss, brauche ich dann diese Threads… die sicherlich besser gelöst werden können aber ich halt noch kein Durchblick dazu habe.

Michael
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
3.896 Beiträge
 
Delphi 12 Athens
 
#20

AW: 2 Threads starten/pausieren...

  Alt 22. Jun 2018, 08:44
Klingt kompliziert, habs jetzt nicht komplett nachvollzogen was du machst ...

Ich würde einfach zwei Threads über Events steuerbar machen, so in der Art, aber die Setter/Getter der Zugriffs-Properties noch sicherheitshalber in TCriticalSections verpacken.
Dann könntest du die Threads intern immer laufen lassen, und ja nach Guste über die Events stillegen oder freischalten.

Dann braucht man kein "Terminate" (nur am Programende, und keine globalen Variablen.

Rollo
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


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 08:53 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