Reputation: 41
I have a process that has spawned multiple threads. Now, to stop and exit the process I can use _exit(0)
. But does this handle the proper termination of all the threads? Is there any way we can kill a process (within itself) and handle a proper termination of all its threads.
Upvotes: 0
Views: 612
Reputation: 14637
Technically, using exit()
or _exit()
anywhere in the program doesn't mean a graceful termination and the program output on termination won't be predictable. Additionally, take a look at the comparison of exit()
vs _exit()
also.
Since, there's no language tag, I'll be elaborating on this problem using pseudo code (perhaps, C++11). Technically, it's a language agnostic problem. The thread APIs are more or less the same for different programming languages.
Here's a simple example of a process (P
) with two threads (T1
and T2
). Something like this:
P
/ \
/ \
T1 T2
Now, we want these threads to print some greeting messages on screen repeatedly after 1 second. Here's the complete example:
// Headers ...
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
// You need something to signal your thread that it should exit.
// So, we're using a global variable to store this information.
volatile bool is_exited = false;
// Here is our callback() or long running task that
// our threads would be executing
void callback()
{
// This loop should exit once is_exited flag's condition is true.
// This loop body is actually indicating the actual job that the
// thread needs to execute.
auto id = this_thread::get_id();
cout << id << ". Started!\n";
while( !is_exited )
{
cout << id << ". Hello!";
this_thread::sleep_for( 1s );
}
cout << id << ". Exited!\n";
}
// Here is our main() function that would start two threads,
// register the callback, and run it. After doing its own processing,
// the main() function would signal threads to stop and wait for them
// to finish their running task and get out of the callbacks. Usually,
// there's a join() or wait() function call to do this. C++ has join().
int main()
{
cout << "main() started!\n";
// Now, register your callback with your threads
// C++ threads start right away after this
// You don't have to call some start() function
thread t1 { callback };
thread t2 { callback };
// So, now that the threads have started the main()
// can do its own things. You could use simple sleep here
// to give some artificial wait.
for ( int i = 0; i < 1000000; ++i )
{
// ...
}
// Now, we need to send the signal to threads to stop their
// execution for a graceful termination.
is_exited = true;
// There's a call to join() function to wait for the
// threads to exit; so here the main() function is waiting
// for the threads to exit. Once the callback() finishes,
// the thread would exit and the main() function would get out
// of these join() calls. And, the program would exit gracefully.
t1.join();
t2.join();
cout << "main() exited!\n";
return 0;
}
Here's the live example: https://ideone.com/NEuCe9
I've tweaked sleep times to get a good output. Observe the output. Specifically look for the threads ids.
Here's the output from this live example:
main() started!
47277466478336. Started!
47277466478336. Hello!
47277464377088. Started!
47277464377088. Hello!
47277466478336. Hello!
47277464377088. Hello!
47277466478336. Hello!
47277464377088. Hello!
47277466478336. Hello!
47277464377088. Hello!
47277466478336. Hello!
47277464377088. Hello!
47277466478336. Hello!
47277464377088. Hello!
47277466478336. Hello!
47277464377088. Hello!
47277466478336. Hello!
47277464377088. Hello!
47277466478336. Hello!
47277464377088. Hello!
47277466478336. Hello!
47277464377088. Hello!
47277466478336. Exited!
47277464377088. Exited!
main() exited!
Upvotes: 1