CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 12 of 12
  1. #1
    Join Date
    May 2002
    Location
    Germany
    Posts
    487

    How to end threads good

    Hi!

    I already solved the problem, but I hope that you have a better solution:

    My app uses at least one worker thread. When started, it handles the communication via the rs232-comport.

    When the user wants to close the whole app., I first tell the worker-thread to close. The last thing it does before leaving is to set a flag. My main program in the meantime just polls in a loop whether that flag is set. When found, it closes also.

    So the worker thread sets the flag that it is closed already! I don't like my software to talk about future states of itself...

    The code is working, but I think it is ineffective.

    Your hints?

    Thanks!

    Marc

  2. #2
    Join Date
    Oct 2002
    Location
    Singapore
    Posts
    3,128
    For the part where your main program waits for the worker thread to end, you can simplify it by using WaitForSingleObject(workerThreadHandle, INFINITE). It basically do the same thing for your except that you don't need to implement the loop.

  3. #3
    Join Date
    May 2002
    Location
    Germany
    Posts
    487
    Thanks for your good and fast answer!
    I tried your hint and failed: The WaitForSingleObject needs 0 ms for the job and in debug mode I see memory leaks...


    //I define globally:
    CWinThread* pThread;

    //On Init:
    pThread = AfxBeginThread(ServerProc, GetSafeHwnd(), THREAD_PRIORITY_NORMAL);

    //When closing:
    WaitForSingleObject(pThread, INFINITE);

    Where is my fault?

    Thanks!
    Marc

  4. #4
    Join Date
    Oct 2002
    Location
    Italy
    Posts
    324
    Write:
    WaitForSingleObject(pThread->m_hThread, INFINITE);

    Regards,
    Marco Era
    www.marcoera.com

    Latest post on my blog: Back to the Amiga's times

  5. #5
    Join Date
    Sep 2003
    Location
    Forever Gone... For Now...
    Posts
    1,515
    Originally posted by Marc from D
    in debug mode I see memory leaks...

    Originally posted by Andreas Masur in many, many threads
    Thought for the day/week/month/year:
    Windows System Error 4006:
    Replication with a nonconfigured partner is not allowed.

  6. #6
    Join Date
    Aug 2001
    Location
    germany
    Posts
    772
    The probably best way to close a thread is to use ExitThread(0) from within the thread. This way everything is cleaned up well. So, you can have something like:

    if (yourCloseFlag)
    ExitThread(0);

  7. #7
    Join Date
    Sep 2003
    Location
    Forever Gone... For Now...
    Posts
    1,515
    Originally posted by Radu
    The probably best way to close a thread is to use ExitThread(0) from within the thread. This way everything is cleaned up well. So, you can have something like:

    if (yourCloseFlag)
    ExitThread(0);
    Whoa! "Everything" is not cleaned up, and it is NOT the best way to close a thread...
    Richter, "Programming Applications for Microsoft Windows":
    You can force your thread to terminate by having it call ExitThread:
    Code:
    VOID ExitThread(DWORD dwExitCode);
    This function terminates the thread and causes the operating system to clean up all of the operating system resources that were used by the thread. However, your C/C++ resources (such as C++ class objects) will not be destroyed. For this reason, it is much better to simply return from your thread function instead of calling ExitThread yourself.
    The recommended way to have a thread terminate is by having its thread function simply return (as described in the previous section). However, if you use the method described in this section, be aware that the ExitThread function is the Windows function that kills a thread. If you are writing C/C++ code, you should never call ExitThread. Instead, you should use the Visual C++ run-time library function _endthreadex.
    Note that calling ExitProcess or ExitThread causes a process or thread to die while inside a function. As far the operating system is concerned, this is fine and all of the process's or thread's operating system resources will be cleaned up perfectly. However, a C/C++ application should avoid calling these functions because the C/C++ run time might not be able to clean up properly
    Making explicit calls to ExitProcess and ExitThread is a common problem that causes an application to not clean itself up properly. In the case of ExitThread, the process continues to run but can leak memory or other resources.
    Thought for the day/week/month/year:
    Windows System Error 4006:
    Replication with a nonconfigured partner is not allowed.

  8. #8
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395
    Hi, Marc!
    Take a look at this article:Using Worker Threads

  9. #9
    Join Date
    May 2003
    Location
    Pakistan
    Posts
    223
    Originally posted by puzzolino
    Write:
    WaitForSingleObject(pThread->m_hThread, INFINITE);



    I think WaitForSingleObject is the best approach

    But it is better if instead of INFINITE one mention a reasonable timeout like 10 sec or so

    pThread->PostThreadMessage(KILL_YOURSELF,0,0)//where KILL_YOURSELF calls AfxEndThread(1,true)
    WaitForSingleObject(*pThread,10000);

    It is little bit better . But it is what i think

  10. #10
    Join Date
    May 2002
    Location
    Germany
    Posts
    487
    As this thread here became larger than expected, I just want to clarify:

    The question was perfectly answered by the hint "WaitForSingleObject". I didn't have a problem in terminating the thread, the only problem I had was that I used an unlogical way to figure out when the thread really stopped. As I'm doing a worker-thread for serial communication, there are neither GUI-objects used nor are there really objects at all.

    Thanks to you all for your hints!

    Marc

  11. #11
    Join Date
    Sep 2003
    Location
    Forever Gone... For Now...
    Posts
    1,515
    Originally posted by Marc from D
    I didn't have a problem in terminating the thread, the only problem I had was that I used an unlogical way to figure out when the thread really stopped.
    To me, "How to end threads good" implies the former rather than the latter...
    Thought for the day/week/month/year:
    Windows System Error 4006:
    Replication with a nonconfigured partner is not allowed.

  12. #12
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626
    I've always used the following system...

    In the GUI thread, set a flag to tell worker threads they should end themselves at their own earliest possible convenience.

    What you do next in the gui thread depends....
    1) If the GUI thread doesn't need any results from the worker threads, just let the GUI thread end normally, while the worker threads are still running/shutting down. The process/application will properly terminate when all of it's threads are closed.
    Note that the user will still see the process active in the taskmanager for some time after he/she has closed the 'application window'. This rarely is an issue anyway.

    2) If the GUI thread must wait for worker threads to finish because it needs to save obtained data or thread progressstatus, needs to do cleanup which can't happen until all threads are closed, you will need to wait for the threads to finish.
    The seemingly obvious (and easy) way to wait for a thread to finish is to use WaitForSingleObject(), but there are a couple catches to this...
    - your program will be unresponsive while it's waiting, which can be a problem if the wait can take a long time.
    - It's somewhat less suited if you have multiple worker threads. Although it's not necessarily bad doing it this way. At the least, you'll be sure the threads have ended, even though the thread you decided to wait on first, may end up being the one that finished last.

    If ending a thread can take a long time, or if you have multiple threads, then I have (and this has worked nicely so far) used the following system...

    When creating a thread, a counter gets incremended, this counter will always contain the number of active threads (excluding the GUI thread). Use InterlockedIncrement().

    When the GUI wants to end, it sets a 'threads_end_yourself' flag. When this flag is set, all (harmfull) menu-items are disabled.
    Threads check this flag in their working loop, and shut themselves down at their own earliest possible convenience.
    At thread end, the thread decrements the flag, and when it hits zero, it posts a user-message telling the GUI all threads are now closed. Each workerthread ends with the code:
    Code:
      if (!InterlockedDecrement(&lNumThreads))
            PostMessage(WM_ALL_THREADS_ENDED, 0,0);
    Or if you use MFC, you can create your own overridden CWinThread, and stuff that code in ExitThread().
    When the GUI receives the WM_ALL_THREADS_ENDED, it does it's cleanup, and terminates.

    It's easy enough to display a "shutting down, please wait" type dialog using this method.

    While it may take a little more work this way. It does provide a clean, safe way to end your app that will work in all cases, provided you follow the three rules below.
    - It won't use ANY significant CPU time, which any form of polling loop (nomatter how smart you can make it) WILL.
    - Your app stays responsive (user can move/size window, there's a proper message telling the app is busy...) while it's shutting down.


    3 rules if you want reliable multithreading code...
    1) Don't use ExitThread()
    2) If think you need to use ExitThread(), then reread rule 1.
    3) If you think you have found a legitimate use of ExitThread(), then reread rule 1.

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