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
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. How to stop the thread if it's running?

How to stop the thread if it's running?

Scheduled Pinned Locked Moved C / C++ / MFC
helptutorialquestion
28 Posts 6 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.
  • R Rajesh R Subramanian

    You need not (and in most cases, MUST NOT) be deleteing a CWinThread object. It cleans up its own mess, unless you change the default value of m_bAutoDelete variable before the thread starts. And if you're thinking of changing the value of m_bAutoDelete , I can almost confidently tell that your approach is wrong (it is so, in 90% of the cases). If you knew what m_bAutoDelete is, you won't be asking here on how to shut down a thread gracefully. Fixed typo!

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

    modified on Thursday, April 30, 2009 4:50 AM

    CPalliniC Offline
    CPalliniC Offline
    CPallini
    wrote on last edited by
    #13

    Rajesh R Subramanian wrote:

    It cleans up its own mess, unless you set the m_bAutoDelete variable to TRUE before the thread starts.

    Is quite the opposite, I suppose. Am I wrong?

    If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
    This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
    [My articles]

    In testa che avete, signor di Ceprano?

    R R 2 Replies Last reply
    0
    • M mikert_2008

      Thanks for the link given. So now I used it like following. CWinThread * myWorkerThread; myWorkerThread = AfxBeginThread(run, this); In ~Destructor() { DWORD result =WaitForSingleObject(myWorkerThread->m_hThread,0); if(result == WAIT_OBJECT_0) delete myWorkerThread; } Is this is the correct apporch to do this? Mike

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

      The issues with what you've done are: 1. You haven't shown us what you're doing inside the 'run' function. (can you please rename it to something other than run, I'm just terrified looking at the context - CWinThread::Run() ... you get the picture) 2. Your WaitFor... call does not 'wait', it just performs a check on a thread which might be running or might be dead, and then attempts to delete something which (again) may have been already dead (you haven't set the m_bAutoDelete to TRUE). You may first try to run a thread successfully, and then try using Events with WaitFor... functions. Simulate processing with Sleep(10) within a loop (for learning purposes) and then shut it down gracefully by setting an Event. You need not 'delete' the CWinThread object, like I said. Give that excellent article another read, and you will be all set. Post a reply, if you're stuck somewhere.

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

      M 1 Reply Last reply
      0
      • CPalliniC CPallini

        Rajesh R Subramanian wrote:

        It cleans up its own mess, unless you set the m_bAutoDelete variable to TRUE before the thread starts.

        Is quite the opposite, I suppose. Am I wrong?

        If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
        This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
        [My articles]

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

        You are FRAKKIN' RIGHT! It was a typo, but now fixed it to something that cannot go wrong. :)

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

        1 Reply Last reply
        0
        • R Roger Stoltz

          I know, I know, I know..... I've modified my previous post even before you replied. You were right in first place Rajesh. I jumped to conclusions from your discussion with Cédric. I'll just put a sock in it now... :-O

          "It's supposed to be hard, otherwise anybody could do it!" - selfquote
          "High speed never compensates for wrong direction!" - unknown

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

          Nah, it looks like I need some coffee as well. Modified my post such that it makes clear sense. :-D

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

          1 Reply Last reply
          0
          • CPalliniC CPallini

            Rajesh R Subramanian wrote:

            It cleans up its own mess, unless you set the m_bAutoDelete variable to TRUE before the thread starts.

            Is quite the opposite, I suppose. Am I wrong?

            If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
            This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
            [My articles]

            R Offline
            R Offline
            Roger Stoltz
            wrote on last edited by
            #17

            CPallini wrote:

            Rajesh R Subramanian wrote:

            It cleans up its own mess, unless you set the m_bAutoDelete variable to TRUE before the thread starts.

            Is quite the opposite, I suppose. Am I wrong?

            Just to be clear: If CWinThread::m_bAutoDelete is set to TRUE, the destructor closes the thread handle. To be able to wait on the thread handle from another thread m_bAutoDelete must be set to FALSE.

            "It's supposed to be hard, otherwise anybody could do it!" - selfquote
            "High speed never compensates for wrong direction!" - unknown

            R CPalliniC 2 Replies Last reply
            0
            • R Roger Stoltz

              CPallini wrote:

              Rajesh R Subramanian wrote:

              It cleans up its own mess, unless you set the m_bAutoDelete variable to TRUE before the thread starts.

              Is quite the opposite, I suppose. Am I wrong?

              Just to be clear: If CWinThread::m_bAutoDelete is set to TRUE, the destructor closes the thread handle. To be able to wait on the thread handle from another thread m_bAutoDelete must be set to FALSE.

              "It's supposed to be hard, otherwise anybody could do it!" - selfquote
              "High speed never compensates for wrong direction!" - unknown

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

              I think Carlo was talking with regards to be able to manually 'delete' the CWinThread object, which can be done with the m_bAutoDelete member set to FALSE. :)

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

              R 1 Reply Last reply
              0
              • R Rajesh R Subramanian

                I think Carlo was talking with regards to be able to manually 'delete' the CWinThread object, which can be done with the m_bAutoDelete member set to FALSE. :)

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

                R Offline
                R Offline
                Roger Stoltz
                wrote on last edited by
                #19

                Rajesh R Subramanian wrote:

                I think Carlo was talking with regards to be able to manually 'delete' the CWinThread object

                I understood it differently. I think he's talking about that your sentence can be interpreted as "if m_bAutoDelete is set to TRUE, CWinThread will not clean up its own mess". You've got a way with words Rajesh. :-D

                "It's supposed to be hard, otherwise anybody could do it!" - selfquote
                "High speed never compensates for wrong direction!" - unknown

                R 1 Reply Last reply
                0
                • R Roger Stoltz

                  Rajesh R Subramanian wrote:

                  I think Carlo was talking with regards to be able to manually 'delete' the CWinThread object

                  I understood it differently. I think he's talking about that your sentence can be interpreted as "if m_bAutoDelete is set to TRUE, CWinThread will not clean up its own mess". You've got a way with words Rajesh. :-D

                  "It's supposed to be hard, otherwise anybody could do it!" - selfquote
                  "High speed never compensates for wrong direction!" - unknown

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

                  Roger Stoltz wrote:

                  I think he's talking about that your sentence can be interpreted as "if m_bAutoDelete is set to TRUE, CWinThread will not clean up its own mess".

                  It occurred to me as well, but I went through the whole conversation again and finally found out something that made sense. Now, let's hope Carlo doesn't come up to tell us he was actually talking about Pasta and Rosemary. :-D

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

                  CPalliniC 1 Reply Last reply
                  0
                  • R Roger Stoltz

                    CPallini wrote:

                    Rajesh R Subramanian wrote:

                    It cleans up its own mess, unless you set the m_bAutoDelete variable to TRUE before the thread starts.

                    Is quite the opposite, I suppose. Am I wrong?

                    Just to be clear: If CWinThread::m_bAutoDelete is set to TRUE, the destructor closes the thread handle. To be able to wait on the thread handle from another thread m_bAutoDelete must be set to FALSE.

                    "It's supposed to be hard, otherwise anybody could do it!" - selfquote
                    "High speed never compensates for wrong direction!" - unknown

                    CPalliniC Offline
                    CPalliniC Offline
                    CPallini
                    wrote on last edited by
                    #21

                    If I recall well, that isn't the whole story, The CWinThread pointer is deleted too. :)

                    If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
                    This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
                    [My articles]

                    In testa che avete, signor di Ceprano?

                    R 1 Reply Last reply
                    0
                    • R Rajesh R Subramanian

                      Roger Stoltz wrote:

                      I think he's talking about that your sentence can be interpreted as "if m_bAutoDelete is set to TRUE, CWinThread will not clean up its own mess".

                      It occurred to me as well, but I went through the whole conversation again and finally found out something that made sense. Now, let's hope Carlo doesn't come up to tell us he was actually talking about Pasta and Rosemary. :-D

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

                      CPalliniC Offline
                      CPalliniC Offline
                      CPallini
                      wrote on last edited by
                      #22

                      Rajesh R Subramanian wrote:

                      Carlo doesn't come up to tell us he was actually talking about Pasta and Rosemary.

                      Nope, you should know, I was actually talking about pizza 'napoli' and beer. :-D

                      If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
                      This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
                      [My articles]

                      In testa che avete, signor di Ceprano?

                      1 Reply Last reply
                      0
                      • CPalliniC CPallini

                        If I recall well, that isn't the whole story, The CWinThread pointer is deleted too. :)

                        If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
                        This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
                        [My articles]

                        R Offline
                        R Offline
                        Roger Stoltz
                        wrote on last edited by
                        #23

                        CPallini wrote:

                        If I recall well, that isn't the whole story, The CWinThread pointer is deleted too.

                        You recall correctly! :thumbsup: There's a delete this; in the destructor as well that is executed if m_bAutoDelete is set to TRUE. I omitted it for brevity since I considered the name of the variable m_bAutoDelete rather self-explanatory. ;) But the only thing the OP need is to read Joe's article over and over again until it's understood. Really.

                        "It's supposed to be hard, otherwise anybody could do it!" - selfquote
                        "High speed never compensates for wrong direction!" - unknown

                        CPalliniC 1 Reply Last reply
                        0
                        • R Roger Stoltz

                          CPallini wrote:

                          If I recall well, that isn't the whole story, The CWinThread pointer is deleted too.

                          You recall correctly! :thumbsup: There's a delete this; in the destructor as well that is executed if m_bAutoDelete is set to TRUE. I omitted it for brevity since I considered the name of the variable m_bAutoDelete rather self-explanatory. ;) But the only thing the OP need is to read Joe's article over and over again until it's understood. Really.

                          "It's supposed to be hard, otherwise anybody could do it!" - selfquote
                          "High speed never compensates for wrong direction!" - unknown

                          CPalliniC Offline
                          CPalliniC Offline
                          CPallini
                          wrote on last edited by
                          #24

                          Roger Stoltz wrote:

                          But the only thing the OP need is to read Joe's article over and over again until it's understood. Really.

                          "Softly spoken magic spells". :)

                          If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
                          This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
                          [My articles]

                          In testa che avete, signor di Ceprano?

                          1 Reply Last reply
                          0
                          • R Rajesh R Subramanian

                            The issues with what you've done are: 1. You haven't shown us what you're doing inside the 'run' function. (can you please rename it to something other than run, I'm just terrified looking at the context - CWinThread::Run() ... you get the picture) 2. Your WaitFor... call does not 'wait', it just performs a check on a thread which might be running or might be dead, and then attempts to delete something which (again) may have been already dead (you haven't set the m_bAutoDelete to TRUE). You may first try to run a thread successfully, and then try using Events with WaitFor... functions. Simulate processing with Sleep(10) within a loop (for learning purposes) and then shut it down gracefully by setting an Event. You need not 'delete' the CWinThread object, like I said. Give that excellent article another read, and you will be all set. Post a reply, if you're stuck somewhere.

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

                            M Offline
                            M Offline
                            mikert_2008
                            wrote on last edited by
                            #25

                            1. Run is simple displaying function. which has nothing to do with CWinThread::Run(). Now it looks like below... CWinThread * myWorkerThread; myWorkerThread = AfxBeginThread(run, this); myWorkerThread->m_bAutoDelete = TRUE; UINT run(LPVOID pParam) { .......... ............ // display the data } In ~Destructor() { DWORD result =WaitForSingleObject(myWorkerThread->m_hThread,0); if(result == WAIT_OBJECT_0) delete myWorkerThread; } 2. In WaitFor... I have given time 0 as I require only to check the status of the thread.

                            R 1 Reply Last reply
                            0
                            • M mikert_2008

                              1. Run is simple displaying function. which has nothing to do with CWinThread::Run(). Now it looks like below... CWinThread * myWorkerThread; myWorkerThread = AfxBeginThread(run, this); myWorkerThread->m_bAutoDelete = TRUE; UINT run(LPVOID pParam) { .......... ............ // display the data } In ~Destructor() { DWORD result =WaitForSingleObject(myWorkerThread->m_hThread,0); if(result == WAIT_OBJECT_0) delete myWorkerThread; } 2. In WaitFor... I have given time 0 as I require only to check the status of the thread.

                              R Offline
                              R Offline
                              Roger Stoltz
                              wrote on last edited by
                              #26

                              mikert_2008 wrote:

                              CWinThread * myWorkerThread;
                              myWorkerThread = AfxBeginThread(run, this);

                              myWorkerThread->m_bAutoDelete = TRUE;

                              In all the confusion from the discussion earlier today you're partly forgiven, but consider the following for spawning the worker thread:

                              CWinThread* pThread;
                              // Create thread suspended to avoid race conditions
                              pThread = AfxBeginThread( run, this, 0, 0, CREATE_SUSPENDED, NULL );

                              // Make sure the thread could be created and
                              // the pointer is valid before operating on it
                              if( pThread )
                              {
                              // Don't let the object delete itself since we want
                              // to be able to wait on the thread handle
                              // This is important and addressed in the article linked to by Carlo!
                              pThread->m_bAutodelete = FALSE;
                              pThread->ResumeThread();
                              }

                              What kind of event stops the worker thread from running? The way I interpret your destructor is that the thread does its job and then terminates by itself. What does the thread do? Your comment "display the data" worries me since you should not touch the GUI from a worker thread in order to avoid deadlocks. Probably you shouldn't be using multithreading at all for the problem you're trying to solve, since you seem to be doing thing sequentially and not in parallel. Your destructor doesn't really make sense. There's also a race condition that in most cases would generate an exception when you're trying to free memory that has already been freed since you haven't set m_bAutoDelete to FALSE. You're mixing manual and automatic deletion of the CWinThread object. You should also make sure all thread spawned by your program are terminated before allowing the program to exit. It's considered Best Practice because when you exit your program you don't have the power to do anything about it any longer. The most harsh way the code that waits for the thread to exit could be like this:

                              if( pThread )
                              {
                              // Here should probably be something that tells the thread
                              // to stop executing such as an event that is signalled

                              if( ::WaitForSingleObject( pThread->m\_hThread, INFINITE ) == WAIT\_OBJECT\_0 )
                              {
                                  // Now it's safe to delete the CWinThread object!
                                  delete pThread;
                                  pThread = NULL;
                              }
                              

                              }

                              You need to get back to the article and read it again as the above suggests that you haven't read it carefully enough and apparently have not understood it properly. Bel

                              1 Reply Last reply
                              0
                              • M mikert_2008

                                Hi, I have created the thread using AfxBeginThread(); function. Now my problem is 1. How to check wheather Thread is running? 2. If it is running then stop/kill the thread. This I will put in the destructor of class (which starts the thread) to do error handling. How to do this? Mike

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

                                mikert_2008 wrote:

                                This I will put in the destructor of class (which starts the thread)...

                                You're starting a thread from within the destructor? :confused:

                                "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
                                • M mikert_2008

                                  Hi, I have created the thread using AfxBeginThread(); function. Now my problem is 1. How to check wheather Thread is running? 2. If it is running then stop/kill the thread. This I will put in the destructor of class (which starts the thread) to do error handling. How to do this? Mike

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

                                  You need two CEvent objects, one representing the request from the primary thread to stop, and the other representing the acknowledgment from the secondary thread that it has stopped. When the primary thread responds to a stop request (e.g., Alt+F4, X, Cancel), it signals the first event and then waits for the second event. In the secondary thread, call WaitForSingleObject() on that event with 0 as the wait time. If it comes back as signaled, signal the other event.

                                  "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
                                  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