Thread aus einem anderen Thread stoppen!



  • Hallo Forum,
    wie kann man am besten mehrere Worker-Threads mit dem Hauptthread stoppen?
    Ich hab jetzt alle Worker-Id's und ihre Handles in einer Liste gespeichert, und meinte wenn ich die Liste durchlaufe und die Handles raushole, so die Threads stoppen zu können!

    // Bsp.
    // in der Schleife, jedes Handle holen und.. 
    ::TerminateThread(hHandle, 0x0); // den Workerthread terminieren
    // hole nächsten hHandle bis die Liste zu ende ist
    

    Klappt noch nicht so richtig gut, dass ist ohne den Hauptthread, ausgelöst über einen Button! Jemand eine Idee wie es besser geht?

    danke
    pixel



  • TeminateThread ist sowieso problematisch, weil es den Thread zu aprupt abwürgt (Thema: Aufräumarbeiten). Nutz lieber eine global verfügbare Variable, die du im Kontrollthread geeignet setzt und in den Arbeitsthreads regelmäßig abfragst.



  • Never ever call TerminateThread!!!
    Du weisst nicht was Du da tust!
    Siehe: Why you should never call Suspend/TerminateThread (Part I--III):
    http://blog.kalmbachnet.de/?postid=6
    http://blog.kalmbachnet.de/?postid=16
    http://blog.kalmbachnet.de/?postid=17

    Verwende entweder eine globale Variable, welche die Threads pollen (schlechte Lösung) oder ein globales (manual Reset) Event welches Du signalisierst und die Threads darauf warten können.



  • Aber wenn man im Thread auf die Signalisierung wartet, kann man ja nix anderes mehr machen?!



  • Jochen Kalmbach schrieb:

    Verwende entweder eine globale Variable, welche die Threads pollen (schlechte Lösung) oder ein globales (manual Reset) Event welches Du signalisierst und die Threads darauf warten können.

    Ich verwende eigentlich immer die erste Variante. Also die.. 👎
    Kannst du bitte hier erklären, weshalb die eine besser als die andere ist bzw. einge Gegenüberstellung der beiden Varianten machen. Evt. wär das dann gleich was für die FAQ 😉
    Thanks a million.



  • wie geht das schrieb:

    Aber wenn man im Thread auf die Signalisierung wartet, kann man ja nix anderes mehr machen?!

    Doch kann man. Schau dir mal WaitForMultipleObjects() an.

    EDIT: Brauchst du nicht unbedingt. Du kannst auch bei WaitForSingleObject() die Zeit angeben, wielange er warten soll.



  • sky21 schrieb:

    Jochen Kalmbach schrieb:

    Verwende entweder eine globale Variable, welche die Threads pollen (schlechte Lösung) oder ein globales (manual Reset) Event welches Du signalisierst und die Threads darauf warten können.

    Ich verwende eigentlich immer die erste Variante. Also die.. 👎
    Kannst du bitte hier erklären, weshalb die eine besser als die andere ist bzw. einge Gegenüberstellung der beiden Varianten machen.

    Der Vorteil ist eigentlich einfach: Du brauchst nicht pollen (pollen ist immer schlecht); somit sparst Du CPU Zeit.



  • Paul_C. schrieb:

    Brauchst du nicht unbedingt. Du kannst auch bei WaitForSingleObject() die Zeit angeben, wielange er warten soll.

    Dann hast Du ja aber nichts gewonnen, da Du ja dann schon wieder pollst (dann halt auf was anders)!



  • Versteh ich aber nicht. Wenn ich WaitForMultipleObjects in einem Thread aufrufe dann schläft der doch und kann nicht seine Aufgabe erledigen.



  • Ja 100% richtig verstanden... Aber die meisten Threads machen nicht ständig was sondern müssen uf was warten und dann machen sie was...
    Aber das hängt natürlich vom speziellen Anwendungfall ab.
    Wenn Du natürlich eine Rechenoperation durchführst die mehrere Minuten / Stunden geht, dann ist es sinnvoller eine globale Variable abzufragen.



  • Events sind zum Aufwecken von Threads geeignet aber nicht zum Stoppen.



  • Naja, implizit schon...
    Du wartest auf den Event (WaitFor...) und wenn *dieser* Signalisiert wird, dann machst Du "return .."



  • Hallo,
    danke für die vielen beiträge, aber irgendwie müssen die threads doch beendet werden können!
    Ich habe einen haupt-thread, das programm selber, in diesem programm starte ich mehrere worker threads, können bis zu 50 oder 60 sein, aber es muß doch eine möglichkeit geben diese zu stoppen, ohne warten zu müssen dass die alle fertig sind!!!
    Schliesslich hab ich ihre id's und handle gespeichert, über die soll das doch gehen können!
    klick auf button stop->dann werden die id's und handles geholt(sind alle in einer CMap) einer nach dem anderen und an die ::TerminateThread(HANDLE hThread) übergeben, nur dass das nicht ganz so klapt! 🙂
    und mit dem WaitForSingleObject(pThread->m_hThrad); , das ich in der thread-function aufrufe, hab ich memoryleaks?ka warum 😕

    grüsse
    pixel



  • pixel schrieb:

    danke für die vielen beiträge, aber irgendwie müssen die threads doch beendet werden können!

    Ein Thread kann sich nur selber beenden. (Punkt)

    pixel schrieb:

    Ich habe einen haupt-thread, das programm selber, in diesem programm starte ich mehrere worker threads, können bis zu 50 oder 60 sein,

    Du solltest vielleicht mal Dein Design überdenken... hört sich für mich ein wenig viel an...

    pixel schrieb:

    aber es muß doch eine möglichkeit geben diese zu stoppen, ohne warten zu müssen dass die alle fertig sind!!!

    Ja. Signalisiere den Threads dass sie sich beenden sollen. Und dann sollten die das tun. Hab ich irgendwo geschrieben das Du warten musst bis sich der Thread beendet hat? (sollte man zwar tun aber notwendig ist dies nicht, wenn er nicht irgendwelche Ressourcen noch aufräumen muss; fazt: es wird empfohlen).

    pixel schrieb:

    Schliesslich hab ich ihre id's und handle gespeichert, über die soll das doch gehen können!

    Das beenden geht darüber nicht... das warten auf den Thread schon 😉

    pixel schrieb:

    klick auf button stop->dann werden die id's und handles geholt(sind alle in einer CMap) einer nach dem anderen und an die ::TerminateThread(HANDLE hThread) übergeben, nur dass das nicht ganz so klapt!

    Und dass es Dir mehrmals erklärt wurde dass dies so nicht geht. Ganz abgesehen davon hast Du wohl auch nicht die Doku zu dieser Funktion gelesen; da steht das auch so...

    pixel schrieb:

    und mit dem WaitForSingleObject(pThread->m_hThrad); , das ich in der thread-function aufrufe, hab ich memoryleaks?ka warum

    Löse zuerst mal das eine Problem, dann können wir über mögliche andere reden...



  • man könnte auch in der loop des threads SleepEx(0,TRUE) aufrufen und wenn er sich beenden soll mit QueueUserAPC() einen function pointer schicken. die funktion ruft der dann auf. in der funktion können dann irgendwelche aufräumaktionen gemacht werden und schliesslich ein ExitThread()



  • @jochen, danke! 🙂
    dann lösen wir das erste problem zu erst, und gehen zu dem nächsten! Die singnale?
    grüsse
    pixel
    👍



  • net schrieb:

    man könnte auch in der loop des threads SleepEx(0,TRUE) aufrufen und wenn er sich beenden soll mit QueueUserAPC() einen function pointer schicken. die funktion ruft der dann auf. in der funktion können dann irgendwelche aufräumaktionen gemacht werden und schliesslich ein ExitThread()

    Wir wollten doch "pollen" verhindern... 🤡
    Und einfach so ExitThread aufzurifen ist eine schlechte Idee, da die meisten Programmierer doch liebend gern die CRT verwenden... somit sollte man zumindest _endthread aufrufen...
    Am einfachsten ist aber einfach ein "return" aus der ThreadProc 😉



  • pixel schrieb:

    dann lösen wir das erste problem zu erst, und gehen zu dem nächsten! Die singnale?

    War das jetzt eine Frage oder eine Vermutung? 🙂



  • Jochen Kalmbach schrieb:

    Am einfachsten ist aber einfach ein "return" aus der ThreadProc 😉

    nur musste den thread dazu kriegen, dass er da auch hinspringt.
    naja, aber wozu gibt es so schicke funktionen wie SetThreadContext()?
    einfach mal eben den instruction pointer von aussen auf das 'return' setzen 😃

    edit: ach, noch was. wem threads zu suspekt sind, der könnte auch 'fibers' nehmen. die laufen in einem thread d.h. man bekommt nicht solche probleme, wenn's ums beenden geht.



  • net schrieb:

    naja, aber wozu gibt es so schicke funktionen wie SetThreadContext()?

    Ich hoffe das war jetzt nicht ernst gemeint 😕 Weil dann kannst Du auch gleich TerminateThread verwenden 🤡



  • Jochen Kalmbach schrieb:

    net schrieb:

    naja, aber wozu gibt es so schicke funktionen wie SetThreadContext()?

    Ich hoffe das war jetzt nicht ernst gemeint 😕 Weil dann kannst Du auch gleich TerminateThread verwenden 🤡

    na, teils/teils. wenn man solche verschärften massnahmen anwendet muss man schon ganz genau wissen was man tut mit so einem 'manuellen context switch'. aber eine möglichkeit ist es auf jeden fall.


Anmelden zum Antworten