http://www.touchdreams.net/blog/2009/01/03/thread-cleanup-handlers-exit-_exit-atexit-and-pthread_exit/

This article describes what happens when a multi-threaded process is shutting down, what are the differences between exit(), _exit() and pthread_exit(), when and what cleanup routines will be called. Shutting down a multi-threaded application gracefully and cleanly is a challenging task. Sometimes you do not even want to do that, but you still need to know what are happening during the shutdown. Although the description here applies to pthread on Solaris, it may shed some light on trouble shooting threading applications on other OSes. You are welcome to add your findings in the comment section.

pthread_exit() can be called by any thread (including the main thread) explicitly. It is also implicitly called when a thread returns from the thread start routine.

When the main thread calls pthread_exit(), only the main thread will terminate and other threads will survive.

When pthread_exit() is called (explicitly or implicitly), any cancellation cleanup handlers that have been pushed and not yet popped are popped in the reverse order that they were pushed and then executed. Then, if the thread has any thread specific data, the associated thread specific data destruct functions will be called in an unspecified order. The above applies to all threads except for the last alive thread in the process.

pthread_exit() does NOT call any routine installed by atexit(). This applies to all threads except for the last thread in the process.

When the last thread in the process calls pthread_exit() (all other threads in the process have been terminated by calling pthread_exit()), the thread specific data destruct functions for this thread will NOT be called, and exit() will be called.

When the main thread returns from main(), exit() (instead of pthread_exit()) is called implicitly.

When exit() (no matter who calls it) is called, all threads will be terminated. Neither thread cleanup handlers nor thread specific data destruct functions will be called.

Calling exit() (or better _exit(), see below) is a quick and dirty way to shutdown the process. When the program is broken or severely corrupted, it might not be a good idea (may core-dump or hang the process) to attempt to shutdown cleanly/gracefully.

If you want to terminate the process without invoking any routine installed by atexit(), call _exit() instead of exit().

When exit() is called, functions that are registered via atexit() are called in the reverse order of their registration.

When multiple threads call exit(), then the behavior is not well specified. For example, on Solaris 9, all the registered function will be called by only one thread (if they were registered before any exit() is called), but they may not finish because another thread that calls exit() may terminate the process. On Solaris 10, all the registered functions will be called by only one thread (if they were registered before any exit() is called), other threads that call exit() wait until all functions are called. If any called function contains an infinite loop, then the process may not terminate.

While exit() is being called, if more functions are registered via atexit() by the same thread (inside any already registered function) or by some other thread, the newly registered functions maybe called by different threads.


Reply via email to