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 1 von 2  1 2      
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.919 Beiträge
 
Delphi 12 Athens
 
#1

AW: 2 Threads starten/pausieren...

  Alt 17. Jun 2018, 21:23
Das würde ich anders lösen. Ich würde das ganze in Pakete aufteilen, die abzuarbeiten sind. Die Größe der Pakete hängt davon ab wie lange es dauert diese zu bearbeiten. Auf die Weise kannst du schnell unterbrechen, auch wenn immer das komplette Paket bearbeitet wird.

Die einzelnen Pakete kannst du dann in eine Queue packen, der Thread holt sich dann jeweils immer das nächste Paket heraus. Die Queue muss natürlich threadsicher sein. Von außen kannst du nun einfach Einfluss auf die Abarbeitung der Pakete nehmen, z.B. indem du ein Paket an Platz eins setzt und so weiter. Auf die Weise kannst du einzelne Pakete priorisieren oder nach hinten schieben.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Dennis07

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

AW: 2 Threads starten/pausieren...

  Alt 18. Jun 2018, 03:00
Das würde ich anders lösen. Ich würde das ganze in Pakete aufteilen, die abzuarbeiten sind. Die Größe der Pakete hängt davon ab wie lange es dauert diese zu bearbeiten. Auf die Weise kannst du schnell unterbrechen, auch wenn immer das komplette Paket bearbeitet wird.

Die einzelnen Pakete kannst du dann in eine Queue packen, der Thread holt sich dann jeweils immer das nächste Paket heraus. Die Queue muss natürlich threadsicher sein. Von außen kannst du nun einfach Einfluss auf die Abarbeitung der Pakete nehmen, z.B. indem du ein Paket an Platz eins setzt und so weiter. Auf die Weise kannst du einzelne Pakete priorisieren oder nach hinten schieben.
Jo, so ließe sich das natürlich auch lösen. Wenngleich sich so eine Lösung wohl eher bei komplexeren Szenarien wirklich auszahlen würde. Bei zwei Paketen braucht man noch keine Queue, finde ich.
Dennis
  Mit Zitat antworten Zitat
MicMic

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

AW: 2 Threads starten/pausieren...

  Alt 18. Jun 2018, 09:25
Danke für die Vorschläge.
Noch etwas schwer für mich... mit first/second oder Queue-Dingsbumbs

Meine eigene Überlegung mit dem Code den ich hier aufgeschrieben habe, ist auch nicht so einfach. Da muss man aufpassen denn sobald die Variablen außerhalb des Threads gesetzt werden, werden diese ja auch im Thread übernommen. Da kommt es dann drauf an, wo der Thread gerade die Zeile verarbeitet. Dennoch habe ich damit weiter probiert und habe es jetzt so:

Code:
 iV := 0;              // Originale Start-Zahl (immer 0)
 iB := Length(FDR)-1;  // Originale End-Zahl (z.B. bis 5000)
 i := 0;               // Ab 0 beginnen
 userpos := false;     // False = normaler Durchgang

 repeat

  daten[i]...

  i := i + 1;

  if ucheck = true then
  begin
   iv := i;
   i := uiv;
   ib := uib;
   if ib > Length(FDR)-1 then ib := Length(FDR)-1;
   ucheck := false;
   userpos := true;
  end;

  if userpos = true then
  begin
   if i>= ib then
   begin
    i := iv;
    ib := Length(FDR)-1;
    userpos := false;
   end;
  end;

 until i >= ib;
Außerhalb des Thread setzte ich dann nach Benuteraktion:
Code:
 Thread1.uiv := neue_start_zahl; // z.B. 200
 Thread1.uib := neue_end_zahl;  // z.B. 1000
 Thread1.ucheck := true;
So geht es einigermaßen aber der Thread wird nicht beendet, wenn der Benutzer ständig Aktionen durchführt. Da muss ich noch rumbasteln. Aber so im Ganzen ist es wohl auch nicht optimal, wenn ich gerade drüber nachdenke.

Eigentlich soll es so sein:
Der Thread soll halt ganz normal von 0-5000 (als Beispiel) die Schleife verarbeiten. Kommt der Benutzer und will (200-1000) dann sollen diese erster verarbeitet werden. Sind diese aber schon durch von der normalen Schleife 0-5000 dann müssen diese 200-1000 nicht verarbeitet werden. Der Benutzer kann jedenfalls zwischen dieser Zeit 200-1000 wieder eine neue Aktion durchführen und will 3000-4000 haben, diese dann aktuell verarbeitet werden sollen, solange diese nicht schon von der normalen Schleife verarbeitet wurden. Ich hoffe das ist verständlich


Zum Glück sind meine "daten[i]..." Sachen (es ist ein Record) so aufgebaut.
Code:
 nr := daten[i].nummer;
 If nr = -1 Then
 Begin
  // ... Daten werden verarbeitet, gesetzt, gespeichert usw.
  // und das kostet etwas mehr zeit (mal 1 sek, mal 5 sek. je nach Inhalt, der immer anders sein kann)
  daten[i].nummer := zahl größer -1;
 End
Also es ist nicht so ganz schlimm, wenn die Schleifenzahl schon mal genutzt wurde.
Ich kenne mich noch nicht so aus mit den Threads und was man alles so damit machen kann. Deswegen denke ich, es wäre der beste Weg, man hat einen Thread für die 0-5000 und ein weiteren Thread für die Benutzeraktion. Wenn der Benutzer-Thread ausgeführt werden soll, soll der 0-5000 Thread pause machen. Das könnte man ja so realisieren, dass die Schleifenzahl nicht weiter hochzählt. Ist der Benutzer-Thread fertig, dann wird die Schleifenzahl vom normalen 0-5000 Thread wieder weiter hochgezählt. Ob nun bei dem einem Thread oder beim anderen die daten[i]... schon verarbeitet wurden oder nicht, wäre ja nicht so schlimm, da ich dieses ja mit "nr := daten[i].nummer" auf "-1" prüfe.

Ich habe schon gelesen, dass es nicht so optimal ist, wenn man Threads pausieren lässt und wieder startet. Wie gesagt, bei dem normalen 0-5000 Thread könnte ich ja zum Pausieren die Schleifenzahl nicht hochzählen lassen und ein Benutzer-Thread erstellen. Ist der Benutzer-Thread fertig, wird er einfach freigegeben. Wenn der normale 0-5000 Thread durch ist und beendet wurde, muss kein Benutzer-Thread mehr erstellt werden (da ja alles von den 0-5000 durch ist). So meine Überlegungen

Michael
  Mit Zitat antworten Zitat
MicMic

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

AW: 2 Threads starten/pausieren...

  Alt 18. Jun 2018, 10:47
Ich habe es jetzt so.
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.
Der geht nun ganz normal durch (mit Repeat/Until-Schleife) und wird nach beenden freigegeben.

Der wird auch nicht pausiert. Aber das würde ich noch gerne einbauen. Daran versuche ich mich gleich.

Der Benutzer-Thread erstelle ich so:
Code:
 if Thread1.Terminated = False Then
 Begin
  UserThread.free;
  UserThread := TUserThread.Create(true);
  UserThread.FreeOnTerminate := false;
  UserThread.iv := UserStartZahl;
  UserThread.ib := UserEndZahl;
  UserThread.Start;
 End;
Solange der Thread1 (0-5000 Thread) läuft, kann ein UserThread erstellt werden.
UserThread.free brauche ich ja hier nicht prüfen oder? Wenn gerade ein UserThread läuft, wird durch "UserThread.free" dieser ja beendet und freigegeben. Wenn keiner läuft, geht "UserThread.free" ja auch, also es machts nichts, wenn keiner freigegeben werden muss. In der Execute von UserThread läuft dann eine For-Schleife (i := iv to ib) ab.

So funktioniert es jedenfalls.

Michael

Geändert von MicMic (18. Jun 2018 um 10:48 Uhr) Grund: True nicht False
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.919 Beiträge
 
Delphi 12 Athens
 
#5

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
AppCentral
  Mit Zitat antworten Zitat
MicMic

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

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
601 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#7

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
Dennis07

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

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
44.340 Beiträge
 
Delphi 12 Athens
 
#9

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.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.919 Beiträge
 
Delphi 12 Athens
 
#10

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
AppCentral
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 21:31 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