Interactions with ThreadsThere are a few important things to keep in mind when dealing with exceptions in a multi-threaded program. Most are pretty straightforward but if forgotten can cause a number of problems. First is that each thread routine is akin to main() and you should not allow exceptions to be thrown out of the thread routine. Provided you created the thread using _beginthread(), and properly initialized the runtime library, your application will exit indicating abnormal program termination. Otherwise you will likely cause the operating system to display an unsightly message about your application and offer to terminate it for you. This is actually worse than throwing an exception from main() which should just indicates abnormal program termination. Trying to use an exception specification on the thread routine in order to get it to call your installed unexpected handler does not seem to work. The application just terminates executes as if no exception specification existed. I'm not sure if this is considered a bug in my compiler or not. The bottom line is that each thread routine should be created using _beginthread() and include a try-block and a catch-all handler just like main() generally does. Next is that each thread routine has its own stack, and hence exception chain. This means that the current exception has to be per thread data and re-throwing an exception is, obviously, only valid within a single thread. The implication is if you have multiple threads which may be working with the same component or group of components and one causes an object to enter an invalid state due to an exceptional condition, your other threads will probably not be aware of this, even if you are properly synchronizing access. The problem is that an exceptional condition in one thread has no way of indicating to another thread that such a condition has occurred. And when your other thread is scheduled it will probably end up encountering an exception as well. This means that an exception in one thread should probably stop the other related threads as well. Of course, subtle problems can arise in how those other threads are stopped. I've usually used an approach where one thread, maybe the main application thread, is ultimately responsible for stopping the dependent threads if one of them stops running. It may also be responsible for stopping other threads and itself if one of the threads it is dependent upon stops running. I've also generally taken the approach that exceptions should get propagated up to the thread routine and should cause the thread to exit, in a normal fashion, which would then allow the managing thread to notice one thread it is dependent upon is not running and shut down all relevant threads. |
|||||||||||