Threads löschen
-
Löscht der Thread denn seinen Eintrag aus der Liste, bevor er sich freigibt, oder trägst Du nur die neuen Threads dort ein? Bei zweiterem ist klar, dass es ein AV gibt: Thread schon beendet und freigegeben, aber Du versuchst darauf zuzugreifen...
-
Hallo,
jeder Thread den ich Anlege wird auch in der TList abgelegt. Es wird an keiner Stelle ein Thread gelöscht.
Nur an der einen Stelle die ich nun programmiere und dabei möchte ich den Thread beenden und zusätzlich den entsprechenden Eintrag aus der TlIst löschen.
Ich habe die Reihenfolge mal umgedreht, bekomme aber immer noch eine Access Violation. Da muss es doch dennoch einen Weg geben.
Grüße Kevin
-
Natürlich bekommst Du eine AV. Du startest Threads mit FreeOnTerminate, löschst die Zeiger aber nicht aus der Liste?!? Von selbst verschwinden die Zeiger da nicht, das mußt Du schon machen. TThreadList heißt nicht, dass damit Threads automatisch verwaltet werden, sondern dass diese Klasse threadsicher ist.
Also entweder nicht FreeOnTerminate verwenden, oder die dafür sorgen, dass die Threads als letzte Aufgabe ihren Zeiger aus der Liste löschen - sonst wird das nie was...
-
Hi,
also sollte es so gehen wenn ich FreeOnTermine false setze?
dann muss ich anstelle von Terminate doch einfach nur delete thread machen und den eintrag aus der TList löschen???
Und on FormDestroy muss ich dann das ganze mit allen Threads machen, damit die auch alle gelösacht werden. Ist das so korrekt?
Kevin
-
Du solltest die Threads auf jeden Fall erst beenden und dann erst löschen...
-
Hallo,
ich habe nun dies versucht:
if (MyThreadList->Count - StrToInt(Del->Text) >= 0) { for (int i = 0; i < StrToInt(Del->Text); i++) { ((TMyThread*)MyThreadList->Items[MyThreadList->Count-1])->Terminate(); MyThreadList->Delete(MyThreadList->Count-1); } }FreeOnTerminate ist immer noch true. Welche Threads ich lösche ist mir auch egal, daher nehme ich die letzten aus meiner TList.
Mittels den Aufruf von Terminate sage ich dem Thread doch, das er nach dem letzten Durchlauf eine execute Schleife beenden soll. Ich löschen Ihn somit nicht selbst. Und danach kann ich den Eintrag ja aus der TList löschen.
Dennoch bekomme ich immer noch eine Access Violation und kann es nicht mehr nachvollziehen.
Kevin
-
Du hast meine Postings gelesen? *zweifel*
Noch einfacher kann ich es nicht erklären:
- Du startest einen Thread mit FreeOnTerminate = true. Den Zeiger auf diesen Thread speicherst Du in einer Liste.
- Dieser Thread ist irgendwann fertig, beendet sich und gibt den Arbeitsspeicher frei
- Dann suchst Du den Zeiger aus der Liste und versuchst auf den Thread zuzugreifen, der nicht mehr existiert: Allgemeine Schutzverletzung.
-
Hi,
klar habe ich deinen Beitrag gelesen. Meine Threads werden irgendwann zur Laufzeit der Anwendung erzeugt. Ich habe NICHT vor diese zu löschen. Daher werden diese bei Beendigung der Anwendung automatisch gelöscht.
Nur über eine Funktion und das ist die wo ich den Quelltext vorgelegt habe, versuche ich die Threads zu beenden. Ich will diese NUR beenden, nicht löschen, denn das löschen geschieht ja automatisch.
Oder wo lösche ich in meinen letzten Quellcodestück den Thread? Die Zeiger verschwinden bisher nicht aus der Liste, da manuel keine Threads beendet werden. Nur halt in meine Quellcodestück und da versuche ich ja den Eintrag aus der Liste zu entfernen.
Wie kann ich es denn machen, dass ein Thread als letzte Aufgabe bekommt sich aus der Liste zu löschen?
// Noch einfacher kann ich es nicht erklären:
// - Du startest einen Thread mit FreeOnTerminate = true. Den Zeiger auf diesen Thread speicherst Du in einer Liste.korrekt, das mache ich
// - Dieser Thread ist irgendwann fertig, beendet sich und gibt den Arbeitsspeicher frei
ja, sobald meine anwendung beendet wird, bzw. die funktion die ich grad versuche zu programmieren.
// - Dann suchst Du den Zeiger aus der Liste und versuchst auf den Thread zuzugreifen, der nicht mehr existiert: Allgemeine Schutzverletzung.
nein, denke ich nicht. kann es zumindest nicht nachvollziehen. alle threads, die ich über die tlist aufrufe existieren auch!!! daher kann ich mir die schutzverletzung nicht vorstellen.
Es mag natürlich auch sein, dass ich irgendwo einen denkfehler habe, da es meine erste multithread anwendung ist und ich sitze nun schon seit 2 tagen an dieser funktion wo ich einfach nur vorzeitig n threads beenden möchte.
kevin
-
Kevin Koel schrieb:
nein, denke ich nicht. kann es zumindest nicht nachvollziehen. alle threads, die ich über die tlist aufrufe existieren auch!!! daher kann ich mir die schutzverletzung nicht vorstellen.
kevinDu kannst gar nicht wissen, ob der Thread noch existiert! Sobald der Thread abgearbeitet ist, wird er automatisch beendet und freigegeben. Sobald dies der Fall ist und Du versuchst auf die Threadinstanz zuzugreifen, gibt es die AV.
Zumindest ist das die wahrscheinlichste Erklärung für die AV, auf Basis der von Dir zur Verfügung gestellten Informationen.
-
Hi,
alle meine Threads laufen in einer Dauerschleife:
void __fastcall TMyThread::Execute() { while(!Terminated) { ... } }Da kann ich also auf nix zugreifen was schon beendet wurde. Da die Threads entweder bei Programmstart automatisch beendet werden oder halt von mir selbst vorzeitig beendet werden, was irgendwie noch nicht will.
Ich rall es einfach nicht.
Kevin
-
Aus der Hilfe des BCB:
Beschreibung
Setzen Sie FreeOnTerminate auf true, wenn Sie Threads nach deren Ausführung nicht explizit freigeben möchten. Wenn FreeOnTerminate den Wert false hat, muß das Thread-Objekt im Programmcode der Anwendung explizit freigegeben werden.
Warnung: Wenn FreeOnTerminate den Wert true hat, kann der Thread von der Methode Execute ausgeführt und freigegeben werden, bevor die Anwendung die nächste Anweisung ausführt. Sofern der Thread bei der Erstellung nicht unterbrochen wurde, dürfen deshalb keine Methoden des Thread-Objekts aufgerufen werden, solange FreeOnTerminate true ist.