Wo einen Thread beenden
-
Hans M. schrieb:
Wo beende ich einen Thread?
threadHandle=CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc, NULL,0,&threadId); // Soll ich gleich das aufrufen? Wo erkenne ich das der Thread beendet wurde? CloseHandle(threadHandle);Wenn Du das Handle nicht brauchst, dann schliesse es doch sofort wieder...
Der Thread wird beendet, wenn Du die "ThreadProc" verlässt...
-
Verstehe jetzt nicht genau. Wartet er bis der Thread beendet ist? Aber ich will ja das er nicht wartet. Das Hauptprogramm soll ja weiter laufen. Nur wenn der Thread beendet ist soll es ja Geschlossen werden. Sorry, aber ich blick da mit den Threads noch nicht ganz durch.
-
Dann musst du entweder aus dem Thread, wenn er fertig ist, eine Nachricht ans Hauptprogramm schicken (wie auch immer, PostMessage, SetEvent, ...), oder aber vom Hauptprogramm aus immer mal wieder prüfen ob er schon "fertig ist".
Prüfen kannst du das indem du mit WaitForSingleObject auf das Thread Handle wartest, mit einem Timeout von 0. Sobald WaitForSingleObject WAIT_OBJECT_0 zurückliefert ist der Thread "fertig" (=hat terminiert).
-
Hans M. schrieb:
Verstehe jetzt nicht genau. Wartet er bis der Thread beendet ist? Aber ich will ja das er nicht wartet. Das Hauptprogramm soll ja weiter laufen. Nur wenn der Thread beendet ist soll es ja Geschlossen werden. Sorry, aber ich blick da mit den Threads noch nicht ganz durch.
Dann schliesse einfach das Handle... das hat mit dem eigentlichen Thread nichts zu tun!
Der Thread wird erst beendet, wenn Du im Thread "return" machst...
-
Jochen Kalmbach schrieb:
Hans M. schrieb:
Verstehe jetzt nicht genau. Wartet er bis der Thread beendet ist? Aber ich will ja das er nicht wartet. Das Hauptprogramm soll ja weiter laufen. Nur wenn der Thread beendet ist soll es ja Geschlossen werden. Sorry, aber ich blick da mit den Threads noch nicht ganz durch.
Dann schliesse einfach das Handle... das hat mit dem eigentlichen Thread nichts zu tun!
Der Thread wird erst beendet, wenn Du im Thread "return" machst...Bzw. _endthread() aufrufst. Jops.
Hans M. schrieb:
Wo erkenne ich das der Thread beendet wurde?Mit:
if(WaitForSingleObject(hThread, 0L) == WAIT_OBJECT_0) // Thread ist beendet... else // Thread läuft noch...Wenn Du einen Thread mit Deinem Programm 'sauber' beenden willst (so nach dem Motto: Wenn mein Programm geschlossen werden _soll_, wird erst der Thread beendet, dann das Programm), was durchaus sinnvoll ist, kannst Du das beispielsweise so machen:
Beispielcode:// Im globalen Scope: typedef struct { bool fAbortThread; // Hier weitere Daten für den Thread... } SThreadData; // in der WndProc: static HANDLE hThread; static SThreadData sdThreadData; // ... switch(uiMessage) { // ... case WM_CREATE: sdThreadData.fAbortThread = false; // Kontrollvariable für den Thread-Abbruch hThread = _bedginthreadex(...) // Thread erstellen // Weiteres... return (0L); // ... case WM_DESTROY: // Benutzer hat Beendigung des Programm gefordert sdThreadData.fAbortThread = true; // Thread für Abbruch freigeben WaitForSingleObject(hThread, INFINITE); // Auf Threadende warten CloseHandle(hThread); // Handle freigeben // Weiteres... PostQuitMessage(0); return (0L); // ... } // Die Bearbeitungsroutine für den Thread: unsigned int __stdcall ThreadProc(void* pvThreadData) { // Zeiger auf Datenstruktur für den Thread holen: volatile SThreadData* pData = static_cast<SThreadData*>(pvThreadData); if(pData->fAbortProcess) { _endthreadex(0); return (0); } // Hier kommen dann die (rechenintentiven) Aufgaben für den Thread, bei denen // aber regelmäßig die Kontrollvariable fAbortProcess auf 'true' geprüft // und der Thread ggf. beendet werden muss. Wichtig vorm Beenden ist auch, // das eventuell allokierter Speicher (new/delete, HANDLE's, etc. ...) vorher // deallokiert bzw freigegeben werden müssen. // Falls es nie zum expliziten Abbruch kommt, wird der Thread hier beenden (bzw. er 'läuft aus'): _endthreadex(0); return (0); }Hoffe die Ausführung ist verständlich/hilfreich/richtig
.EDIT: Siehe folgende Posts/Kritik. (Änderung unter WM_DESTROY)
-
Die Raketen sind nicht sehr hilfreich. Benutz einfach INFINITE bei WaitForSingleObject.
-
ll schrieb:
Die Raketen sind nicht sehr hilfreich. Benutz einfach INFINITE bei WaitForSingleObject.
Hehe
... Doch eigentlich schon, denn falls auch irgendeinem Grund der Thread hängt, hängt auch das ganze Programm...ein ungeduldiger Benutzer wird dann (wahrscheinlich) zweierlei tun:1. Er wird sich über Dein Programm ärgern, da dies (gerade vorm Beenden) ja nicht so einfach hängen bleiben kann (auch wenns vom Programmierer ja nur gut gemeint war, im Sinne eines _sauberen_ Beendens).
2. Er wird schnell zum Task-Manager greifen, der dann eben TerminateThread aufruft (da er ja hängt :p ). Es kommt in diesem Punkt also aufs selbe raus... .
Ich weiß, dass man die Verwendung von TerminateThread vermeiden sollte (bzw. unterlassen sollte), aber hier ist es in meinen Augen schon sinnvoll. Wenn man den obrigen Code noch etwas optimieren will, so kann man das hier noch einfügen: [url=http://winapi.net/index.php?inhalt=s30]
TerminateThread und die Ressourcen-Freigabe[/url].
-
CodeFinder schrieb:
Ich weiß, dass man die Verwendung von TerminateThread vermeiden sollte (bzw. unterlassen sollte), aber hier ist es in meinen Augen schon sinnvoll.
Es ist NICHT Sinnvoll. So ein Code deutet nur darauf hin, dass Du nicht sauber Programmieren willst/kannst!
Siehe auch mein Blog zu Terminate/SuspendThread...
-
Jochen Kalmbach schrieb:
CodeFinder schrieb:
Ich weiß, dass man die Verwendung von TerminateThread vermeiden sollte (bzw. unterlassen sollte), aber hier ist es in meinen Augen schon sinnvoll.
Es ist NICHT Sinnvoll. So ein Code deutet nur darauf hin, dass Du nicht sauber Programmieren willst/kannst!
Siehe auch mein Blog zu Terminate/SuspendThread...Hm...Naja ich habe das in meinem Programm so gemacht und vorher geprüft, wie oft, bzw. ob überhaupt das TerminateThread erreicht wird. Das war nie der Fall. Daher dachte ich nur, das es für den allerletzten Nofall doch sinnvoll wäre
.
Die Logik des Programm sorgt eigentlich perfekt dafür, das die Funktion nicht zur Ausführung kommt, von daher ist das schon sauber programmiert. Also Du meinst trotzdem, wech damit
? Hm ok, wech damit, und auf TimeOut auf INFINTE, is ja nit die Welt
-thX!-
-
CodeFinder schrieb:
Hm ok, wech damit, und auf TimeOut auf INFINTE, is ja nit die Welt
-thX!-
-
Oder den User mit einer MessageBox darüber informieren das dein Programm fehlerhaft ist und dann terminieren.

-
Bevor ich TerminateThread aufrufe, ruf' ich lieber gleich terminate() auf

p.S.: ja, steht ja schon da, direkt über meinem Posting. Vielleicht sollte ich mal lesen lernen
-
Na, dann würde ich eher einen MiniDump generieren und diesen Per E-Mail mir zukommen lassen. Dann könnte ich zumindest gleiche sehen, WARUM der Thread sich nicht beendet hat.
-
Jochen Kalmbach schrieb:
Na, dann würde ich eher einen MiniDump generieren und diesen Per E-Mail mir zukommen lassen. Dann könnte ich zumindest gleiche sehen, WARUM der Thread sich nicht beendet hat.
Deswegen ja terminate() und nicht abort().
set_terminate() und du bist mit Minidump und allem Schnick-Schnack mit dabei