CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11

Thread: Stop a Thread

  1. #1
    Join Date
    Aug 2000
    Location
    Virginia, US
    Posts
    158

    Stop a Thread

    How do I stop a thread? I'm using ::TerminateThread within this code and the thread keeps running. Is this the correct procedure? Thanks for any help.

    Code:
    void CPageTwo::OnBnClickedButTest()
    {
    	// Click First to Start Thread
    	// Click Again to End Thread
    	if(!m_pThread) // Start Thread
    	{
    		m_pThread = AfxBeginThread(ThreadFunc, this);
    		if(!m_pThread)
    		{
    		  // Could not create thread
    		  return;
    		}
    	}
    	else // End the thread
    	{
    		::TerminateThread( m_pThread, 0 );
    		m_pThread = 0;
    	}
    }
    
    UINT CPageTwo::ThreadFunc(LPVOID lpParam)
    {
    	CPageTwo* p2 = (CPageTwo*)lpParam;
    
    	for(int i = 0; i < 100; ++i)
    	{
    		p2->PostMessage(WM_UPDATE_PROGRESS, 0, (LPARAM)i);
    		Sleep(2000);
    	}
    	return 0;
    }

  2. #2
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: Stop a Thread

    Quote Originally Posted by cbpetro View Post
    How do I stop a thread? I'm using ::TerminateThread ...
    Don't use TerminateThread. From the documentation at http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx :
    Quote Originally Posted by MSDN
    TerminateThread is a dangerous function that should only be used in the most extreme cases. You should call TerminateThread only if you know exactly what the target thread is doing, and you control all of the code that the target thread could possibly be running at the time of the termination. For example, TerminateThread can result in the following problems: [list of really bad things omitted -- go look at the link]
    Do you have an "extreme case" that justifies the use of this "dangerous function"? Of course you don't.

    In answer to your question of "how do I stop a thread", it's the thread itself that should monitor something that tells it to stop, and then the thread should simply exit from its THREADFUNC. For example, assuming that your class will create at most one thread, modifying your code gives the following:
    Code:
    void CPageTwo::OnBnClickedButTest()
    {
    	// Click First to Start Thread
    	// Click Again to End Thread
    	if(!m_pThread) // Start Thread
    	{
    		m_bStop = FALSE; // this is a BOOL member variable
    		m_pThread = AfxBeginThread(ThreadFunc, this);
    		if(!m_pThread)
    		{
    		  // Could not create thread
    		  return;
    		}
    	}
    	else // End the thread
    	{
    		// ::TerminateThread( m_pThread, 0 );
    		m_bStop = TRUE; 
    
    		m_pThread = 0;
    	}
    }
    
    UINT CPageTwo::ThreadFunc(LPVOID lpParam)
    {
    	CPageTwo* p2 = (CPageTwo*)lpParam;
    
    	for(int i = 0; i < 100; ++i)
    	{
    		p2->PostMessage(WM_UPDATE_PROGRESS, 0, (LPARAM)i);
    		Sleep(2000);
    
    		if (p2->m_bStop)
    			break;
    
    	}
    	return 0;
    }
    Note that this is very rudimentary and relies on a few assumptions (such as atomicity of the change of m_bStop to TRUE, only one single thread since otherwise they would all be stopped, etc.) There are better and more robust methods, but in the end the principle is the same: tell the thread it's time to stop and then let the thread terminate itself by exiting from the THREADFUNC.

    Mike

    PS: Your code probably doesn't work because the thread handle doesn't have the THREAD_TERMINATE access right. See the docs. But you would learn a lot if you called GetLastError after the TerminateThread function fails.

  3. #3
    Join Date
    Aug 2000
    Location
    Virginia, US
    Posts
    158

    Re: Stop a Thread

    Quote Originally Posted by MikeAThon View Post
    There are better and more robust methods, but in the end the principle is the same: tell the thread it's time to stop and then let the thread terminate itself by exiting from the THREADFUNC.

    Mike
    Mike,

    Thanks for your help, I'm starting to understand. I have one follow up question that maybe you or someone else can help with. I used AfxEndThread in the ThreadFunc because MSDN recommends this for cleanup.

    My question is, Is there a way for calling function to get the status of the thread when it's completed, or stopped. I can do this by setting m_pThread = 0, but this does'nt seem proper if m_pThread is a pointer.

    Code:
    void CPageTwo::OnBnClickedButTest()
    {
    	// Click First to Start Thread
    	// Click Again to End Thread
    	if(!m_pThread) // Start Thread
    	{
    		m_bStop = FALSE; // this is a BOOL member variable
    		m_pThread = AfxBeginThread(ThreadFunc, this);
    		if(!m_pThread)
    		{
    		  // Could not create thread
    		  return;
    		}
    	}
    	else // End the thread
    	{
    		m_bStop = TRUE;
    		m_pThread = 0;
    	}
    }
    
    UINT CPageTwo::ThreadFunc(LPVOID lpParam)
    {
    	CPageTwo* p2 = (CPageTwo*)lpParam;
    
    	for(int i = 0; i < 5; ++i)
    	{
    		if (p2->m_bStop)
    			AfxEndThread(0, TRUE);  //EXIT CODE = ?, DELETE THREAD = TRUE
    
    		p2->PostMessage(WM_UPDATE_PROGRESS, 0, (LPARAM)i);
    		Sleep(1000);
    	}
    
    	p2->m_bStop = FALSE;   // 
    	p2->m_pThread = 0;	   // Set the thread to O to let calling funtion know it's done - Ugly
    	AfxEndThread(0, TRUE); // EXIT CODE = ?, DELETE THREAD = TRUE
    	return 0;
    }

  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Stop a Thread

    This is all explained in MSDN:

    http://msdn.microsoft.com/en-us/libr...=vs.80%29.aspx
    Remarks

    Must be called from within the thread to be terminated.

    For more information on AfxEndThread, see the article Multithreading: Terminating Threads.
    http://msdn.microsoft.com/en-us/libr...=vs.80%29.aspx

    Regards,

    Paul McKenzie

  5. #5
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Stop a Thread

    Quote Originally Posted by cbpetro View Post
    ... I used AfxEndThread in the ThreadFunc because MSDN recommends this for cleanup.
    You should not. Just return any UINT number (so called "error code") from within the thread procedure. MFC framework will then call AfxEndThread exactly where and when it is needed!
    Victor Nijegorodov

  6. #6
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: Stop a Thread

    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  7. #7
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: Stop a Thread

    Quote Originally Posted by cbpetro View Post
    ... My question is, Is there a way for calling function to get the status of the thread when it's completed, or stopped.
    What do you mean by "calling function"? And what do you mean by "status" of a thread that's already completed? To me, the status of a thread that's completed is self-evidently "completed".

    Have the others here answered your other questions?

  8. #8
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: Stop a Thread

    GetExitCodeThread

    Remarks

    This function returns immediately. If the specified thread has not terminated and the function succeeds, the status returned is STILL_ACTIVE. If the thread has terminated and the function succeeds, the status returned is one of the following values:
    • The exit value specified in the ExitThread or TerminateThread function.
    • The return value from the thread function.
    • The exit value of the thread's process.
    Last edited by Igor Vartanov; May 23rd, 2012 at 11:28 PM.
    Best regards,
    Igor

  9. #9
    Join Date
    Aug 2000
    Location
    Virginia, US
    Posts
    158

    Re: Stop a Thread

    Quote Originally Posted by MikeAThon View Post
    What do you mean by "calling function"? And what do you mean by "status" of a thread that's already completed? To me, the status of a thread that's completed is self-evidently "completed".

    Have the others here answered your other questions?
    Mike,

    When you use the boolean to stop the thread, the thread is only stopped. The m_pThread is still a pointer to CWinThread. It seems to me, there may be three conditions you may want to account for...

    1.) The thread is stopped and the user wants to RESTART the thread.
    2.) The thread is stopped and the user wants to RESUME the thread.
    3.) The thread was allowed to run and is completed.

    Code:
    // I refer to this as the "calling function"
    void CPageTwo::OnBnClickedButTest()
    {
    	// Click First to Start Thread
    	// Click Again to End Thread
    	if(!m_pThread) // Start Thread - My problem is here.  Can I check if thread is completed? or is stopped?
    	{
    		m_bStop = FALSE; // this is a BOOL member variable
    		m_pThread = AfxBeginThread(ThreadFunc, this);
    		if(!m_pThread)
    		{
    		  // Could not create thread
    		  return;
    		}
    	}
    	else // End the thread
    	{
    		m_bStop = TRUE;
    		m_pThread = 0;
    	}
    }


    MSDN is kinda vague on handling threads and I haven't found a good example anywhere on the net.

  10. #10
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Stop a Thread

    Quote Originally Posted by cbpetro View Post
    ...
    When you use the boolean to stop the thread, the thread is only stopped. The m_pThread is still a pointer to CWinThread. It seems to me, there may be three conditions you may want to account for...
    No, it is not correct.
    When thread procedure returns thread terminates (exits).
    You should not care about what still m_pThread points to, unless you haven't set the CWinThread::m_bAutoDelete to false. If you set it to false then you will have to delete this m_pThread object yourself.

    You might want to check out this excellent Joe Newcomer's essay about Using Worker Threads
    Victor Nijegorodov

  11. #11
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: Stop a Thread

    Quote Originally Posted by cbpetro View Post
    ... It seems to me, there may be three conditions you may want to account for....
    No, as noted by VictorN, that's not correct. The thread ends when the thread function exits, so there is nothing left to "resume".

    It is, of course, possible to write code for a thread pool, i.e., a pool of threads that sit idle until an event signals them that there is work to do. In such an architecture, threads can be "paused" and they can be "resumed". But that seems like something that you should aspire to in the future, not today.

    For now, simply allow the thread to exit. If a user wants to start new thread-related work, then simply create a new thread.

    Mike

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured