Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. How to terminate the secondary thread when the application closed?

How to terminate the secondary thread when the application closed?

Scheduled Pinned Locked Moved C / C++ / MFC
c++helptutorialquestion
9 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    susanne1
    wrote on last edited by
    #1

    Hallo, I have an application that uses a secondary thread to excute a very long function, what i need is, how to terminate the secondary thread "CLEANLY" if the main appliction is going to be closed while the seconndary thread is still excuting the verx long function? i started with : ON_WM_Close() in the View.cpp file, but i do not know how to continue: The secondary thread should become a Message if the the x or End in the Main application werde clicked. Please help(with code).

    R D 2 Replies Last reply
    0
    • S susanne1

      Hallo, I have an application that uses a secondary thread to excute a very long function, what i need is, how to terminate the secondary thread "CLEANLY" if the main appliction is going to be closed while the seconndary thread is still excuting the verx long function? i started with : ON_WM_Close() in the View.cpp file, but i do not know how to continue: The secondary thread should become a Message if the the x or End in the Main application werde clicked. Please help(with code).

      R Offline
      R Offline
      Rajesh R Subramanian
      wrote on last edited by
      #2

      The secondary thread can execute its code within a spin loop, which can wait for an event to "happen" (with a wait time of 0 ms). While you want to close your application, just set that particular event so that the secondary thread would have a chance to clean itself up properly. You could similarly use another event (with a timeout) that the secondary thread would "set" to inform the main thread that it has finished cleaning up and is on its way to terminate. Take a look at WaitForSingleObject[^]. Attempt it, and if you get stuck somewhere, or if you don't understand any of it, post it here (with relevant source code, if any). MTRecalc[^] sample makes use of events, which you can refer to.

      It is a crappy thing, but it's life -^ Carlo Pallini

      S 1 Reply Last reply
      0
      • R Rajesh R Subramanian

        The secondary thread can execute its code within a spin loop, which can wait for an event to "happen" (with a wait time of 0 ms). While you want to close your application, just set that particular event so that the secondary thread would have a chance to clean itself up properly. You could similarly use another event (with a timeout) that the secondary thread would "set" to inform the main thread that it has finished cleaning up and is on its way to terminate. Take a look at WaitForSingleObject[^]. Attempt it, and if you get stuck somewhere, or if you don't understand any of it, post it here (with relevant source code, if any). MTRecalc[^] sample makes use of events, which you can refer to.

        It is a crappy thing, but it's life -^ Carlo Pallini

        S Offline
        S Offline
        susanne1
        wrote on last edited by
        #3

        bool PrintMy Results(const CString& strMyResult) { bool bTerminate = false; while(!bTerminate && nCount < arrMyResults.GetSize()) { if (::WaitForSingleObject(m_End_Event.m_hObject, 0) == WAIT_OBJECT_0) { bTerminate = true; continue; } nCount++; // Code to print the Array-Elements // I am hier inside the secondary thread wich is in another // class as the Doc class, how can I till him hier that the //application is going to be finsihed and he must finsh the printing //of the last line of the Array? } }

        R S 2 Replies Last reply
        0
        • S susanne1

          bool PrintMy Results(const CString& strMyResult) { bool bTerminate = false; while(!bTerminate && nCount < arrMyResults.GetSize()) { if (::WaitForSingleObject(m_End_Event.m_hObject, 0) == WAIT_OBJECT_0) { bTerminate = true; continue; } nCount++; // Code to print the Array-Elements // I am hier inside the secondary thread wich is in another // class as the Doc class, how can I till him hier that the //application is going to be finsihed and he must finsh the printing //of the last line of the Array? } }

          R Offline
          R Offline
          Rajesh R Subramanian
          wrote on last edited by
          #4

          WARNING: I don't have VS on this machine, I've typed the code out manually and I've no way to compile it. I've verified whatever I can, but please make sure that it works fine before you use it. Use it at your own risk, keep out of reach of children, do not expose to sunlight, etc., Global handle variables to store the event:

          HANDLE hDieNow, hImDead; //Global variables

          Function where you'd create the events (preferably InitDialog or something like that):

          CMyDialog::OnInitDialog()
          {
          //other stuff

          //create the events here
          hDieNow = CreateEvent(NULL, TRUE, FALSE, NULL);
          hImDead = CreateEvent(NULL, TRUE, FALSE, NULL);

          //Please look into the documentation of CreateEvent to know about the parameters.

          return TRUE;
          }

          Thread function:

          UINT ThreadFunc(LPVOID pFuncParams)
          {
          while(true)
          {
          if(WaitForSingleObject(hDieNow, 0) == WAIT_OBJECT_0)
          break;

          else
          {
          //Your thread code should be here.
          Sleep(100);
          OutputDebugString(_T("Thread probe...\n"));
          }
          }
          SetEvent(hImDead); //Tell the main thread that clean up is complete.
          return false;
          }

          Application close handler function:

          CMyDialog::OnClose()
          {
          SetEvent(hDieNow); //Tell the thread to stop everything and do clean up.
          DWORD dwResult = WaitForSingleObject(hImDead, 5000); //Give the thread 5 seconds to clean up.
          //Check the value of dwResult. It must be WAIT_OBJECT_0, if the wait succeeded!

          //Proceed to quit the application. The thread must be dead now.
          }

          It is a crappy thing, but it's life -^ Carlo Pallini

          S 1 Reply Last reply
          0
          • R Rajesh R Subramanian

            WARNING: I don't have VS on this machine, I've typed the code out manually and I've no way to compile it. I've verified whatever I can, but please make sure that it works fine before you use it. Use it at your own risk, keep out of reach of children, do not expose to sunlight, etc., Global handle variables to store the event:

            HANDLE hDieNow, hImDead; //Global variables

            Function where you'd create the events (preferably InitDialog or something like that):

            CMyDialog::OnInitDialog()
            {
            //other stuff

            //create the events here
            hDieNow = CreateEvent(NULL, TRUE, FALSE, NULL);
            hImDead = CreateEvent(NULL, TRUE, FALSE, NULL);

            //Please look into the documentation of CreateEvent to know about the parameters.

            return TRUE;
            }

            Thread function:

            UINT ThreadFunc(LPVOID pFuncParams)
            {
            while(true)
            {
            if(WaitForSingleObject(hDieNow, 0) == WAIT_OBJECT_0)
            break;

            else
            {
            //Your thread code should be here.
            Sleep(100);
            OutputDebugString(_T("Thread probe...\n"));
            }
            }
            SetEvent(hImDead); //Tell the main thread that clean up is complete.
            return false;
            }

            Application close handler function:

            CMyDialog::OnClose()
            {
            SetEvent(hDieNow); //Tell the thread to stop everything and do clean up.
            DWORD dwResult = WaitForSingleObject(hImDead, 5000); //Give the thread 5 seconds to clean up.
            //Check the value of dwResult. It must be WAIT_OBJECT_0, if the wait succeeded!

            //Proceed to quit the application. The thread must be dead now.
            }

            It is a crappy thing, but it's life -^ Carlo Pallini

            S Offline
            S Offline
            susanne1
            wrote on last edited by
            #5

            thanks. I am using SDI application, so i will put the code in BOOL OnNewDocument() instead of OnInitDialg(). Now a general question: why can i not use ON_WM_CLOSE() to tell the small thread to terminate himself and if yes how? Thanks a lot

            R 1 Reply Last reply
            0
            • S susanne1

              thanks. I am using SDI application, so i will put the code in BOOL OnNewDocument() instead of OnInitDialg(). Now a general question: why can i not use ON_WM_CLOSE() to tell the small thread to terminate himself and if yes how? Thanks a lot

              R Offline
              R Offline
              Rajesh R Subramanian
              wrote on last edited by
              #6

              susanne1 wrote:

              I am using SDI application, so i will put the code in BOOL OnNewDocument() instead of OnInitDialg().

              Do it wherever. You just need to create those events, before you would use it. But be sure on that, or the WaitFor... call is going to fail and you'll not get desired results.

              susanne1 wrote:

              Now a general question: why can i not use ON_WM_CLOSE() to tell the small thread to terminate himself and if yes how?

              What do you mean how? I just demonstrated that to you with an example in my previous post. Just set the event that the worker thread is spinning on (waiting to be set) and then wait for the worker thread to set the "I'm dead" event (which is kind of an acknowledgment from the thread that the cleanup is complete).

              It is a crappy thing, but it's life -^ Carlo Pallini

              1 Reply Last reply
              0
              • S susanne1

                Hallo, I have an application that uses a secondary thread to excute a very long function, what i need is, how to terminate the secondary thread "CLEANLY" if the main appliction is going to be closed while the seconndary thread is still excuting the verx long function? i started with : ON_WM_Close() in the View.cpp file, but i do not know how to continue: The secondary thread should become a Message if the the x or End in the Main application werde clicked. Please help(with code).

                D Offline
                D Offline
                David Crow
                wrote on last edited by
                #7

                When asked to close, the primary thread needs to signal an event that the secondary thread is monitoring. Once signaled, the primary thread would then wait for the secondary thread to finish. This is very easy to do with two CEvent objects. [edit] I now see that Rajesh has an excellent example. [/edit]

                "Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown

                "Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons

                1 Reply Last reply
                0
                • S susanne1

                  bool PrintMy Results(const CString& strMyResult) { bool bTerminate = false; while(!bTerminate && nCount < arrMyResults.GetSize()) { if (::WaitForSingleObject(m_End_Event.m_hObject, 0) == WAIT_OBJECT_0) { bTerminate = true; continue; } nCount++; // Code to print the Array-Elements // I am hier inside the secondary thread wich is in another // class as the Doc class, how can I till him hier that the //application is going to be finsihed and he must finsh the printing //of the last line of the Array? } }

                  S Offline
                  S Offline
                  Stuart Dootson
                  wrote on last edited by
                  #8

                  As you've shown this code, here's a potential solution:

                  1. Ensure there is a volatile LONG variable (let's call it lTerminate) visible to both your main thread's code and your second thread's code. Initialise that variable to 0 before the second thread is started

                  2. When you start the second thread, store its handle somewhere it can be seen by the code that will terminate the thread.

                  3. The second thread's loop should look like this:

                    bool PrintMy Results(const CString& strMyResult)
                    {
                    while(!lTerminate && nCount < arrMyResults.GetSize())
                    {
                    nCount++;
                    // Code to print the Array-Elements
                    // I am hier inside the secondary thread wich is in another // class as the Doc class, how can I till him hier that the //application is going to be finsihed and he must finsh the printing //of the last line of the Array?
                    }
                    }

                  4. When you want to exit, set lTerminate to 1 with an appropriate function (as I'll show you below) and wait for the thread's handle to be set, as that indicates the thread has exitted:

                    ::InterlockedExchange(&lTerminate, 1);
                    ::WaitForSingleObject(hSecondThread, INFINITE);

                  Easy as...

                  Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                  R 1 Reply Last reply
                  0
                  • S Stuart Dootson

                    As you've shown this code, here's a potential solution:

                    1. Ensure there is a volatile LONG variable (let's call it lTerminate) visible to both your main thread's code and your second thread's code. Initialise that variable to 0 before the second thread is started

                    2. When you start the second thread, store its handle somewhere it can be seen by the code that will terminate the thread.

                    3. The second thread's loop should look like this:

                      bool PrintMy Results(const CString& strMyResult)
                      {
                      while(!lTerminate && nCount < arrMyResults.GetSize())
                      {
                      nCount++;
                      // Code to print the Array-Elements
                      // I am hier inside the secondary thread wich is in another // class as the Doc class, how can I till him hier that the //application is going to be finsihed and he must finsh the printing //of the last line of the Array?
                      }
                      }

                    4. When you want to exit, set lTerminate to 1 with an appropriate function (as I'll show you below) and wait for the thread's handle to be set, as that indicates the thread has exitted:

                      ::InterlockedExchange(&lTerminate, 1);
                      ::WaitForSingleObject(hSecondThread, INFINITE);

                    Easy as...

                    Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                    R Offline
                    R Offline
                    Rajesh R Subramanian
                    wrote on last edited by
                    #9

                    Sweet! Have my vote, sir. :)

                    It is a crappy thing, but it's life -^ Carlo Pallini

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups