0

After some reading it seems to me that there is no portable way to guarantee that a detached std::thread will not cause memory leaks or even undefined behavior once the main thread finishes execution. It obviously can't be joined once it has been detached, there doesn't seem to be a mechanism to detect whether detached threads exit from the main thread and the STL does not provide an analogue of pthread_exit.

It seems to me that this implies that once I detach a thread I basically have to pray that is has finished executing before the main thread returns from main or bad things might happen. Is this correct? Or am I missing something?

Peter
  • 2,919
  • 1
  • 16
  • 35
  • Are you sure you need a detached `thread`? – Iman Nia Nov 01 '20 at 13:56
  • Which c++ standard are you using? – Iman Nia Nov 01 '20 at 13:57
  • @Iman: C++11, I have edited the question. And yes, I am sure, I know it's untypical but there is a part of my code where I really can't wait synchronously for a thread to finish execution. This is not a problem in 99% of all cases but sometimes the thread continues execution until the end of main, at which point I don't know how to deal with it. – Peter Nov 01 '20 at 14:00
  • Use a wait on an std::condition_variable at the end of main() that you notify in the threaded code when it completes. It doesn't matter whether the thread object is still attached. – Hans Passant Nov 01 '20 at 14:05
  • @HansPassant: That seems sensible, I'll try it. – Peter Nov 01 '20 at 14:08
  • Don't detach if you want to wait on the thread completion. Then it becomes trivial: signal the thread to end, then `join` with it. – rustyx Nov 01 '20 at 14:22
  • @rustyx: The problem with that is that it seems like threads _have_ to complete before the end of the program. So why would you every call `detach`? Obviously you usually shouldn't but if using it never made sense it wouldn't be an option. – Peter Nov 01 '20 at 14:42
  • You can `detach` when you don't care when the thread ends, like when calling legacy C code which never returns. But in your case you do care, obviously. See [When should I use std::thread::detach?](https://stackoverflow.com/questions/22803600/when-should-i-use-stdthreaddetach) – rustyx Nov 01 '20 at 14:54
  • @Peter the main application of detach is to run a new application! We will have a new heap area. If you detach your threads you have almost no control on it. But with the description you have provided, I believe you shouldn’t use detach watch cppcon concurrency by arthur o’dywer. You will get the idea how to do it. Threads have been improved in c++20 but it is far from 11 that you are using, yet the good news is you still can use pthread library, however I strongly recommend to plan an upgrade for 20 which will become available soon (by the end of 2020 they promised). – Iman Nia Nov 01 '20 at 16:46
  • If you have a thread that last more than your main thread, consider refactoring your could to make it the main thread. You may need to add some functionality to it and migrate some code from your main thread. This sounds more logical instead of waiting at the end of main thread to join your side thread and forget the detached ever existed. – Iman Nia Nov 01 '20 at 16:48

1 Answers1

0

to guarantee that a detached std::thread will not cause memory leaks

When main has finished, memory leaks are generally not an issue, because program is about to terminate anyway.

or even undefined behavior once the main thread finishes execution

Don't touch global state in the thread, nor any automatic variables from main. Or if you do, then don't detach.

It seems to me that this implies that once I detach a thread I basically have to pray that is has finished executing

Not quite. You don't necessarily need to care about the thread finishing. If you do need to care, then don't detach that thread.

How to guarantee termination of detached C++ thread?

You cannot. At most, you can guarantee that the thread has finished its work by waiting on a condition variable in main and setting the variable at the end of the thread. This is for most purposes a complicated way to re-implement join.

eerorika
  • 232,697
  • 12
  • 197
  • 326