Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficient exit from multithreaded application (specifics)

I've read a few sources on proper methods of bubbling a message out from a thread to all other threads to exit gracefully (every thread performs it's own exit routine). Of these, I liked the idea of a global atomic boolean that can be flagged from any thread, and all other threads check this flag to perform an exit routine - when all threads are joined, the main thread can then exit the application.

Purely computation threads would probably be handled differently, right?

Is this efficient and safe? Is there a better way to do this?

Thanks!

like image 762
oneminute Avatar asked Dec 01 '10 13:12

oneminute


2 Answers

I'm not a fan of threads checking boolean (or other) status variables to know when to do what, because it's wasteful. The threads would have to spin, constantly checking the variable to see if there are new instructions. This burns the CPU.

A better option is to create a semaphore or in Windows an event, and have all the threads wait on that. The threads can sleep while they arent busy, and wont steal time slices from other threads doing real work simply to check a variable.

like image 157
John Dibling Avatar answered Oct 06 '22 19:10

John Dibling


In Windows, I use QueueUserAPC to call a function which throws an exception, causing threads to exit cleanly.

I wrote more about the details in this answer here:

How do I guarantee fast shutdown of my win32 app?

In summary, here's what happens:

Say thread A wants to terminate thread B (and then C, D, ...)

  • Thread A calls QueueUserAPC(), passing the handle to thread B and the address of a function which will throw an Exception of class MyThreadExit.
  • Thread B runs normally until it calls something that checks for alertable waits. Maybe WaitForSingleObjectEx, maybe SleepEx, or something else.
  • At this point, thread B runs the APC function passed earlier, causing the exception to be thrown in Thread B.
  • All stack-allocated objects get automatically destructed correctly as the exception makes thread B 'unwind' its stack.
  • The outermost thread function of thread B will catch the exception.
  • Thread B now exits, possibly signalling to Thread A that it's done.
like image 31
Roddy Avatar answered Oct 06 '22 19:10

Roddy