![]() |
Threads werden automatisch beendet
Hallo Freunde,
ich programmiere eine Multithreadanwendung, OnFormCreate des Hauptprogramms Create ich die anderen zwei Threads gleich mit. IM Taskmanager wird meine Anwendung auch mit 3Threads (Haupt + 2 zusätzliche) angezeigt. Wenn ich nun den einen Thread mit Terminate beende, zeigt mir die Taskmangaer an, dass mein Prgramm nur noch zwei Threads umfasst. Wenn ich aber wieder Porgrammablauf starte, dann funktioniert noch alles. a) Wie krieg ich raus, welchen Thread er beendet? b) Beendet er wirklich einen Thread? c) Wie kann ich diese Willkür beenden oder d) Ist das ein Fehler vom Taskmanager? Ich bin euch wie immer sehr verbunden Boss |
Re: Threads werden automatisch beendet
Überwache es doch mal in Deinem Delphi unter: Ansicht->Debug Fenster->Threads.
|
Re: Threads werden automatisch beendet
Zitat:
Zitat:
|
Re: Threads werden automatisch beendet
also, ich habe festgestellt, dass mit terminate der thread beendet wird und dann nicht mehr erscheint, allerdings existiert er noch, denn wenn ich resume aufrufe, kommt kein fehler. wie kann ich einen terminierten thread wieder reaktivieren?
der thread soll bestehen bleiben, die aktion mit terminate ist aber so schön um denthread definiert zu beenden. |
Re: Threads werden automatisch beendet
Ich rate jetzt einfach mal, weil du immer noch die nötigen Informationen beharrlich verschweigst.
Du benutzt die TThread-Klasse der VCL. Dein Thread-Objekt ist global. Die Eigenschaft FreeOnTerminate steht bei dir auf False, somit wird die Instanz des Thread nicht wieder freigebene und ein weiterer Aufruf der Methode Resume schlägt nicht fehl. |
Re: Threads werden automatisch beendet
Zitat:
Zitat:
Zitat:
Zitat:
Edit: kein roter Kasten ... :roll: |
Re: Threads werden automatisch beendet
lucki hat recht, tut mir leid, fragt halt, wenn ich nicht das richtige erzähle..
habe ich jetzt ne while not terminated schleife in ne endlosschleife gepackt.. nach while not terminated kommt suspend, dann könnte ich mit resume evtl fortfahren, ich probier's mal aus, denn jedes mal den thread neu createn ist ja auch nicht fein |
Re: Threads werden automatisch beendet
Zitat:
Delphi-Quellcode:
Das sollte gehen ...
while(not terminated)do
begin // Mach was hier ... Suspend(); end; Immer wieder einen neuen Thread erzeugen erzeugt sogar jede Menge Overhead, da hast du ganz recht. |
Re: Threads werden automatisch beendet
Warum sind die Variablen denn global? Ist doch vollkommen unnötig und führt hier wieder nur zu Problemen, wie man sieht bei der Fehlersuche.
Deine Lösung habe ich nicht verstanden. Versuch dich mal etwas besser auszudrücken. Zitat:
|
Re: Threads werden automatisch beendet
hat aber auch nicht geklappt
so von wegen: while(true) do begin while not terminated do begin end; suspend; end; // forever Ritti (12:43 PM) : ich kann den thread nicht einfach mit suspend abwürgen, weil da externe hardware dranhängt, deren einer befehl erst abgearbeitet werden muss, bevor ein neuer kommt. |
Re: Threads werden automatisch beendet
poste am besten mal ein bisschen code, vor allem die stellen, an denen die Threads erstellt, gestartet, beendet und wieder freigegeben werden.
aber mal ne ganz andere frage: wo kann man im Taskmanager denn sehen, wie viele Threads ein Programm benutzt? |
Re: Threads werden automatisch beendet
Zitat:
Nachtrag: Du wolltest doch den Thread quasi nur nach jedem Schleifendurchgang schlafenlegen? Dann mach's wie ich es oben gezeigt habe. Zitat:
|
Re: Threads werden automatisch beendet
Also, hier der Text des Threads:
Delphi-Quellcode:
Ich hab jetzt FreeOnterminate:=true gesetzt. Und create nen neuen Thread, wenn die Messung/der Thread wieder aufgenommen werden sollen.
procedure Mythread.Execute;
var fehlerzaehler:integer; instream,weitergabe:tArray; begin SetName; fehlerzaehler:=0; setlength(instream,0);setlength(instream,c_laen); setlength(weitergabe,0);setlength(weitergabe,c_laen); while not terminated do begin if UsbParIn(c_DevNum,instream,c_laen) then begin fehlerzaehler:=instream[0]; weitergabe:=instream; //DarstThread.Resume; end else begin inc(fehlerzaehler); if fehlerzaehler=3 then begin Synchronize(Neu_beginnen); //hauptform benachrichtigen end; end; { Thread-Code hier einfügen } end; ReturnValue:=3; end; Seht ihr noch ne andere Möglichkeit den Thread am Ende der Schleife zu unterbrechen und von dort wieder loslaufen zu lassen? |
Re: Threads werden automatisch beendet
Zitat:
|
Re: Threads werden automatisch beendet
danke, olli, aber leider kann ich nicht suspend benutzen, da der eine befehl erst vollständig abgearbeitet werden muss.
Ich habe das Problem jetzt anders gelöst, nun steht aber ein neues: wie würdet ihr denn dem einen thread, der schneller ist, von einem langsameren thread ein datenpaket konfliktfrei übermitteln, ohne dass der langsamere dazu angehalten oder synchronisiert werden muss? der langsamere (Messung) soll weiterlaufen, ohne unterbrechung, während der schnellere fix die grafik aktualisiert. dazu muss ich ein paket (array of word) übergeben. Danke, euch fleiß'gen Helfern!! |
Re: Threads werden automatisch beendet
mir kommt es so vor als ob du nicht ganz verstehst was ein Thread ist bzw. wie er funktioniert. Es macht absolut keinen Sinnn innerhalb eine Threads suspend aufzurufen. Denn wenn man einen Thread schlafen schickt dann läuft dieser nicht und kann somit nicht suspend aufrufen, das suspend muss also wenn dann von außerhalb aufgerufen werden.
Und einen Thread am Ende der schleife anhalten kannst du ganz einfach mit sleep und ähnlichen Funktionen... [Edit]Der Inhalt des Beitrages ist falsch!! Ich hatte Suspend mit Resume verwechselt[/Edit] |
Re: Threads werden automatisch beendet
hey, kann sein, dass ich nicht alles verstehe, aber das wolltest du mir nicht vorwerfen, oder?
hast du nicht lieber eine lösung, für mein problem, "quasiparallele abarbeitung" der Messwerterfassung und Grafikaktualisierung? die messwerte müssen ja dazu an den thread "grafikaktualisierung" übermittelt werden, der dann die daten auch auf die platte schmeißt. ?? Danke dir, Sir |
Re: Threads werden automatisch beendet
du holst dir einfach jede sekunde mit einem Timer in deinem Hauptprogramm die Daten und zeichnest aus denen das Diagramm. und wenn die Messungen sehr zeitkritsch sind, lässt du die halt weiterhin in einem thread machen.
also so:
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
var Daten: TDaten; begin Daten := RechenThread.GetDaten; Self.DrawDiagram(Daten); end; |
Re: Threads werden automatisch beendet
Zitat:
Zitat:
Zitat:
@BlackJack: a.) geht auch das nicht ohne Synchronisation, b.) bitte keine Timer. Wenn er schon Threads benutzt, dann auch konsequent. Da wären Timer nur Ressourcenverschwendung. |
Re: Threads werden automatisch beendet
Um Threads zu synchronisieren, verwendet man Synchronisierungsobjekte, also Semaphoren, Mutexe, events etc. Schau mal in der OH oder in der WinAPI-Hilfe nach CreateSemaphore.
|
Re: Threads werden automatisch beendet
Zitat:
Zitat:
|
Re: Threads werden automatisch beendet
Zitat:
Nur bei DWORD, Word und Byte (und auf Win64 auch ULONGLONG) kannst du atomares Lesen und Schreiben ohne viel Brimborium garantieren. Natürlich würde man, wenn Lesen und Schreiben getrennt stattfinden, auch getrennte Critical Sections benutzen. Das mit den grafischen Komponenten verwechselst du schonmal mit der VCL und TThread. Dies ist nicht voll allgemeingültig. |
Re: Threads werden automatisch beendet
Meine Threads sehen i.a. immer so aus ('Workerthreads'):
Delphi-Quellcode:
Das 'hndSemaphore' ist ein mit 'CreateSemaphore' erzeugtes Handle auf eine Semaphore. Das ist sowas wie ein Zähler.
Procedure TMyThread.Execute;
Begin While Not Terminated do If WaitForSingleObject (hndSempahore, dwMyTimeout) = WAIT_OBJECT_0 Then // führe den Auftrag aus else // Timeout Verarbeitung End; WaitForSingleObject wartet solange, bis die Semamphore (der Zähler) > 0 ist. Mit 'ReleaseSemaphore' 'addiert' man etwas zur Semaphore und kann so dem Thread sagen, das er loslegen soll. Das Ganze ist absolut Threadsicher. Ich würde einen Thread schreiben, der im Hintergrund Daten einliest und in einen Buffer schreibt (z.B. einem FIFO oder Queue). Nach dem Schreiben eines Datenpaketes, oder wenn der Buffer halbvoll ist oder so, wird ein zweiter Thread angestossen, der die Daten aus dem Buffer ausliest und weiterverarbeitet (z.B. zeichnet). Dieser zweite Thread wird natürlich auch über eine Semaphore angestossen. Wenn ich die Weiterverarbeitung nur mit einem Zeitgeber (threadgesteuert oder als Timer) mache, kann es passieren, das der Buffer zu voll wird. Der Vorteil dieser Methode ggü einem einfachen Suspend/Resume ist die mögliche Behandung eines Timeouts. Ich finde es auch nicht ästhetisch, wenn ein Thread sich per Suspend selbst schlafen legt. Aber das ist Geschmackssache. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:13 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