20

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?

code
  • 5,294
  • 16
  • 62
  • 113
  • 4
    Related/duplicate: http://stackoverflow.com/q/12207684 – dyp Sep 04 '14 at 00:50
  • 2
    To reiterate what's said on this question and elsewhere, what you're doing now, and even what you seem to want to do, is unsafe. The main thread returning kills off `globalThread` in a non-graceful fashion, and the only "right" way to do things is to have the main thread send a request via `mutex`, etc., to break its loop, and have the main thread `join` to wait for graceful termination acknowledgement. – Jeff Sep 04 '14 at 01:01
  • Check this out - [MY SOLUTION][1] . I have answered the similar question . [1]: http://stackoverflow.com/a/32338982/5163650 – Bharat Jain Sep 01 '15 at 19:05
  • 1
    Try TerminateThread() if it's Windows. It looks like it could be Windows based on those function calls. – Owl Aug 19 '16 at 14:11

6 Answers6

17

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.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • 18
    I think a `mutex` is overkill for a simple flag. Sounds to me more like a job for `atomic` or `atomic_flag`. – dyp Sep 04 '14 at 00:59
  • @dyp I concur, but even that won't guarantee the thread is terminated before `main()` exits. – WhozCraig Sep 04 '14 at 01:07
  • 2
    @avakar and you join a **detached** thread... how? The OP has already established the thread is detached; there is nothing to join. – WhozCraig Sep 04 '14 at 01:11
  • 5
    @WhozCraig, I'd join it by noticing step 1, "do not detach the thread". – avakar Sep 04 '14 at 01:13
  • @avakar likewise. I would too. The short answer to the OP's question as-stated is, you simply can't. (the title question is different than the closing body question, unfortunately). – WhozCraig Sep 04 '14 at 01:14
  • While this answer may be true for Linux, please note that under Windows it's not accurate... there is a function called TerminateThread()... – Owl Aug 19 '16 at 14:06
  • @Owl - does that Windows function result in a proper exception getting thrown in the thread all the way up to the thread entry point, properly unwinding the stack and invoking the destructor of all class instances that go out of scope as a result of the exception? Because if not, it can't be used in any non-trivial C++ code, or you'll end up with undefined behavior. – Sam Varshavchik Aug 19 '16 at 21:39
  • @Sam indeed, but the code provided has no exceptions and is trivial. – Owl Aug 25 '16 at 11:03
  • Sometimes I wish the stdlib had inherited `boost::thread::interrupt`... sometimes. In theory it's probably best to force us to do this explicitly, even if that means lots of timed condition variable waits and whatnot. – Lightness Races in Orbit Aug 30 '16 at 18:03
  • As of C++ 20, we now have jthread, which does exactly the same things that you suggested (it contains a variable and watches it until it signal the thread to stop). – Nguyễn Nhân Feb 19 '23 at 04:59
3

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.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • 3
    This is misleading. Again you are generalising about all code everywhere. Please stop doing this. Some threads don't need cleanup, for example, there are scenarios where you have 2 or more threads racing to find a solution to something and no data is written or transmitted until a solution is found, when this happens, it's absolutely fine to accept the solution of the winning thread, kill the threads that haven't found a solution with no concern whatsoever about data corruption. IPC, signal handling? All glossed over in your statement. – Owl Aug 26 '16 at 08:10
  • @Owl I said there is no way to cleanly shutdown a detached thread. You gave an example of a case where you *don't* cleanly shutdown a detached thread. You are arguing against something I did not say. – David Schwartz Aug 26 '16 at 15:49
  • 1) You cannot see any way to "clean up" a thread without waiting for a join. I actually think that's wrong. 2) My point was that some threads don't need cleaning up, that's not quite the same as what you think i'm saying. – Owl Aug 27 '16 at 09:53
  • I said there is no way to cleanly shutdown a detached thread and explained why. This answers the question the OP asked. There's no reason to think the OP thinks it's essential to always cleanly shutdown all threads, and I never said or implied it was, just answered his question. – David Schwartz Aug 28 '16 at 05:36
  • That's not what OP asked though, Op asked how it is possible, not your opinion on whether it is possible - they are totally different questions. – Owl Aug 29 '16 at 17:09
  • @Owl OP asked how it's possible, and the answer is that it's not possible. Opinions are irrelevant. – David Schwartz Aug 29 '16 at 17:30
  • Maybe it might help if you could list the things in a terminated thread that cannot be cleaned up, and we'll go through each one. – Owl Aug 30 '16 at 12:02
  • @Owl The thing that needs to be cleaned up is the thread itself. This is a C++ question. Attributes of particular C++ implementations are not relevant. – David Schwartz Aug 30 '16 at 17:54
  • Did you mean clearing it up through pthread_attr_destroy()? What precisely needs to be cleared up here? The heap? That can be freed up by another thread. – Owl Aug 31 '16 at 08:16
  • @Owl I'm not talking about attributes, I'm talking about the thread itself. The thing that joining the thread does or the thing that a detached thread does automatically when it terminates -- cleaning up whatever is associated with the thread (which can vary from platform to platform). – David Schwartz Aug 31 '16 at 08:40
  • @Owl I think you miss the point that a platform can do whatever it wants so long as it complies with the standard. And the standard only provides two ways to clean up after a thread -- joining it or having it terminate normally after being detached. That's it. And if it's detached, there's is absolutely no way you can tell when or whether it has terminated. – David Schwartz Aug 31 '16 at 08:42
  • Some compilers like Microsoft Visual Studio for example don't follow standards in C99 or C0XX, only C89, so what you are saying isn't true, although that may change soon. You know when a thread is terminated if you explicitly killed that thread. If you signalled it to finish, again you know that the thread has terminated if you give a grace period, so that's not true either. Also of all the companies i've worked in, none have followed standards, ever. Even IBM / HP / Nokia etc do not follow standards. – Owl Aug 31 '16 at 09:15
  • 1
    @Owl "you know that the thread has terminated if you give a grace period"?! Please, tell me how long the grace period has to be and where you find this wisdom. – David Schwartz Aug 31 '16 at 09:23
  • If you kill a thread, it stops processing as soon as it's killed. That's the time it takes for the thread to be killed. A few seconds is overkill. – Owl Aug 31 '16 at 09:34
  • @Owl Sure, that's plenty of time -- until it's not and your code breaks (because the clock jumped or the system suspended or who knows what). It's fine to write crappy code that works some of the time, but it's nearly criminal to teach people to do it without making it clear that that's what you're doing. – David Schwartz Aug 31 '16 at 09:56
  • 1) You should never ever measure time periods using a timezoned clock, that's asking for trouble. 2) If your system is suspended / or there's an issue with swapping for example and OMD kicks in and goes on it's murdering rampage, things like this, what makes you think that threads would behave normally anyway? Threads can behave in very complex ways, some threading problems are provably insoluble. Trying to suggest that a complicated threaded system that is a delicate house of cards of timing conditions anyway (because there's no other way to solve the issue) is "crappy", is wrong. – Owl Aug 31 '16 at 10:04
  • Actually to add to that, the best way to measure time in this situation would be to measure the CPU time that the process / thread gets. There are functions for doing this, and if you see things like suspend / swapping problems etc then it would factor in these issues. – Owl Aug 31 '16 at 10:10
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/122287/discussion-between-david-schwartz-and-owl). – David Schwartz Aug 31 '16 at 11:49
2

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

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
2

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.

djg
  • 131
  • 9
0

You can terminate the detached thread by setting its condition to break the loop though the pointer.

You can also wait for that thread until it finishes execution using semaphore.

Lex
  • 29
  • 1
  • 4
0

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.

joejoe
  • 1
  • 2