Thread aus einem anderen Thread stoppen!



  • 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.



  • Bitte bring mal Beispielcode Jochen.



  • net schrieb:

    eine möglichkeit ist es auf jeden fall.

    Da kann ich Dir nur wiedersprechen... wer sowas macht (also den Thread "abschiesst" egal ob jetzt mittels TerminateThread oder SetThreadContext) kann gleich ExitProcess aufrufen...



  • :-)) schrieb:

    Bitte bring mal Beispielcode Jochen.

    Ist das denn soo schwierig?

    Also hier die Event gesteuerte Version:

    #include <stdio.h>
    #include <windows.h>
    #include <tchar.h>
    
    DWORD WINAPI MyThread(LPVOID pData)
    {
      HANDLE hWaitHandles[2];
      hWaitHandles[0] = (HANDLE) pData;
      hWaitHandles[1] = CreateEvent(NULL, FALSE, FALSE, NULL);
      DWORD dwRes;
      do
      {
        dwRes = WaitForMultipleObjects(2, hWaitHandles, FALSE, INFINITE);
        if (dwRes == WAIT_OBJECT_0+1)
        {
          // es gibt was anderes zu tun...
        }
      } while (dwRes != WAIT_OBJECT_0);
      CloseHandle(hWaitHandles[1]);
      return 0;
    }
    
    int _tmain()
    {
      HANDLE hEndEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
      DWORD dwThreadId;
      HANDLE hThread = CreateThread(NULL, 0, MyThread, hEndEvent, 0, &dwThreadId);
      // mache noch was anderes...
      SetEvent(hEndEvent);
      WaitForSingleObject(hThread, INFINITE);
    }
    

    Und hier mit der globalen Variable:

    #include <stdio.h>
    #include <windows.h>
    #include <tchar.h>
    
    bool volatile g_bEndThread = false;
    
    DWORD WINAPI MyThread(LPVOID pData)
    {
      while(g_bEndThread == false)
      {
        // do some long running calculation
      }
      return 0;
    }
    
    int _tmain()
    {
      DWORD dwThreadId;
      HANDLE hThread = CreateThread(NULL, 0, MyThread, NULL, 0, &dwThreadId);
      // mache noch was anderes...
      g_bEndThread = true;
      WaitForSingleObject(hThread, INFINITE);
    }
    


  • Melde mich auch wieder zurück.
    Das, was ich am Anfang über WaitForSingleObject() gesagt habe, da hat Jochen natürlich Recht. Dann wäre man beim Polling. Sorry.
    Aber jemand schrieb hier (unregistriert: "event-spezialist"), dass man Events nicht zum Beenden nutzen sollte?
    Wieso nicht? Finde ich persönlich eine wunderbare Lösung.
    Wie sollte es sonst gehen? Außer mit der globalen Variable? :xmas1:



  • In MyThread auch noch ein Event erstellen? Wofür das?



  • Paul_L. schrieb:

    In MyThread auch noch ein Event erstellen? Wofür das?

    Das hab ich nur mal so reingemacht um anzudeuten, dass der Thread ja eigentlich was tun sollte... und dies natürlich auch Ereignisgesteuert... somit gibt es einen zweiten Event der die eigentliche Arbeit für diesen Thread signalisiert (siehe auch in die do-while-Schleife 😉 )



  • Jochen Kalmbach schrieb:

    net schrieb:

    eine möglichkeit ist es auf jeden fall.

    Da kann ich Dir nur wiedersprechen... wer sowas macht (also den Thread "abschiesst" egal ob jetzt mittels TerminateThread oder SetThreadContext) kann gleich ExitProcess aufrufen...

    nene, mit SetThreadContext() kann man threads nicht bloss abschiessen. damit kannste alle registerinhalte ändern, einschliesslich stackpointer, ip, flagregister usw. ich hab' das mal verwendet um ein rtos (scheduling) zu simulieren unter windoof.
    btw: wenn die threadproc auf ein return' trifft, springt der thread zu 'ExitThread()'. das kannste im debugger nachvollziehen. mickrichweich kocht auch bloss mit wasser 😉



  • net schrieb:

    flagregister usw. ich hab' das mal verwendet um ein rtos (scheduling) zu simulieren unter windoof.

    OT: Da hättest Du Dir lieber Fibers anschauen sollen, damit kannst Du ein User-Mode Scheduler bauen...

    net schrieb:

    btw: wenn die threadproc auf ein return' trifft, springt der thread zu 'ExitThread()'.

    Was willst Du mir jetzt damit sagen?



  • Jochen Kalmbach schrieb:

    net schrieb:

    btw: wenn die threadproc auf ein return' trifft, springt der thread zu 'ExitThread()'.

    Was willst Du mir jetzt damit sagen?

    das:

    Jochen Kalmbach schrieb:

    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 😉



  • Jochen hat doch geschrieben, dass das eine schlechte Lösung ist?!?


Anmelden zum Antworten