Supriya
Supriya

Reputation: 41

How to stop a process that has spawned multiple threads

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

Answers (1)

Azeem
Azeem

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

Related Questions