简体   繁体   中英

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

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?

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.

There is no way to cleanly shutdown a detached thread. Doing so would require waiting for the cleanup to complete, and you can only do that if the thread is joinable.

Consider, for example, if the thread holds a mutex that another thread needs to acquire in order to cleanly shut down. The only way to cleanly shut down that thread would be to induce it to release that mutex. That would require the thread's cooperation.

Consider if the thread has opened a file and holds a lock on that file. Aborting the thread will leave the file locked until the process completes.

Consider if the thread holds a mutex that protects some shared state and has put that shared state temporarily into a inconsistent state. If you terminate the thread, either the mutex will never be released or the mutex will be released with the protected data in an inconsistent state. This can cause crashes.

You need a thread's cooperation to cleanly shut it down.

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....

In noticing that the straight forward answer of "NO" is less than helpful:

Generally you will see the answer being akin to "use your own inter thread communication"

Whether that is an atomic bool being shared between the main thread and the child thread or whether that is signalling a thread with another thread via OS methods.

It may be helpful to shift the focus to the specifics of WHEN you would like a detached thread to die, rather than 'who does the killing'.

https://en.cppreference.com/w/cpp/thread/notify_all_at_thread_exit

Looking at code examples like the above helped me with what I was dealing with (main thread dying obscurely and children segfaulting) and I hope it helps you.

You can make your thread a member variable. Launch it where you want and join in destructor.

Also you can make a condition variable in the thread loop and function that sets it to false and calls join() on thread.

Works for me.

I think the best way is to create signal handler

#include <iostream>
#include <csignal>

using namespace std;

void signalHandler( int signum ) {
   cout << "Interrupt signal (" << signum << ") received.\n";

   // cleanup and close up stuff here  
   // terminate program  

   exit(signum);  
}

int main () {
   // register signal SIGINT and signal handler  
   signal(SIGINT, signalHandler);  

   while(1) {
      cout << "Going to sleep...." << endl;
      sleep(1);
   }

   return 0;
}

https://www.tutorialspoint.com/cplusplus/cpp_signal_handling.htm this is the site where I got the code. You can also use raise function to create signal in the code. Checkout the link.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM