Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to terminate or stop a detached thread in c++?

Tags:

I am interested in terminating/stopping/killing a detached thread in c++. How can this be done?

void myThread()
{
    int loop = 0;
    while(true)
    {
        std::this_thread::sleep_for(std::chrono::seconds(5));
        ++loop;
    }
}

void testThread()
{
    std::thread globalThread(myThread);
    globalThread.detach();
}

int main(void)
{
    testThread();
    for(unsigned int i=0; i < 1000; i++)
    {
        cout << "i = " << i << endl;
    }
    return 0;
}

The reason why I'd like to "stop"/"terminate" the globalThread() is because valgrind lists that this is a "possibly lost" type of memory leak (152 bytes). What is the best way to deal with this?

like image 247
code Avatar asked Sep 04 '14 00:09

code


People also ask

How do you terminate a thread?

A thread automatically terminates when it returns from its entry-point routine. A thread can also explicitly terminate itself or terminate any other thread in the process, using a mechanism called cancelation.

What happens to a detached thread when main () exits?

The answer to the original question "what happens to a detached thread when main() exits" is: It continues running (because the standard doesn't say it is stopped), and that's well-defined, as long as it touches neither (automatic|thread_local) variables of other threads nor static objects.

What is thread detach in C?

Allows storage for the thread whose thread ID is in the location thread to be reclaimed when that thread ends. This storage is reclaimed on process exit, regardless of whether the thread was detached, and may include storage for thread's return value.


2 Answers

There are no provisions to stop another thread; whether it's detached, or joinable.

The only way to stop a thread, is for the thread to return from the initial thread function.

In this particular case, I would suggest the following changes:

  1. Do not detach the thread. Instantiate it in main().
  2. Add a bool value, and a std::mutex, the bool gets initialized to false
  3. Each time through the thread's inner loop, lock the mutex using a std::unique_lock, take the bool's value, then unlock the mutex. After unlocking the mutex, if the bool was true, break out of the loop, and return.
  4. In main(), before exiting: lock the mutex, set the bool flag to true, unlock the mutex, then join the thread

This is not perfect, since it will take up to five seconds for the second thread to check the bool flag, and return. But, this would be the first tep.

like image 137
Sam Varshavchik Avatar answered Oct 22 '22 11:10

Sam Varshavchik


You could drop below the C++ Standard and use OS-specific functions, such as sending your own process a signal while setting the signal mask so it's delivered only to the detached thread - a handler can set a flag that's polled from your thread. If your main routine waits longer than the poll period plus a bit you can guess it should have terminated ;-P. The same general idea can be used with any other signalling mechanism, such as an atomic terminate-asap flag variable.

Alternatively, and only as a last resort, there's pthread_cancel and similar. Note that async cancellation like this is a famously dangerous thing to do in general - you should be careful that the thread you terminate can't be in any code with locked/taken resources or you may have deadlocks, leaks, and/or undefined behaviour. For example, your code calls std::this_thread::sleep_for(std::chrono::seconds(5)); - what if that asks the OS for a callback when the interval expires, but the function to continue to afterwards uses the terminated thread's stack? An example where it can be safe is if the thread's doing some simple number crunching in a loop within your app.

Otherwise Sam's answer documents an alternative if you avoid detaching the thread in the first place....

like image 27
Tony Delroy Avatar answered Oct 22 '22 12:10

Tony Delroy