You want to call std::thread::detach
on the thread. After detach
returns, it is safe to destroy the std::thread
object as the thread is no longer associated with the object and will continue running independently.
The following code demonstrates using detach
.
Sample Code
#include <iostream>
#include <thread>
#include <chrono>
using std::cout, std::endl;
using namespace std::chrono_literals;
template<class F>
void create_detached_thread(F&& func) {
std::thread th{std::forward<F>(func)};
th.detach();
}
int main(int argc, const char *argv[]) {
cout << "Main started" << endl;
create_detached_thread([]() {
cout << "First thread starting" << endl;
std::this_thread::sleep_for(400ms);
cout << "First thread done" << endl;
});
create_detached_thread([]() {
cout << "Second thread starting" << endl;
std::this_thread::sleep_for(200ms);
cout << "Second thread done" << endl;
});
cout << "Main sleeping" << endl;
std::this_thread::sleep_for(1s);
cout << "Main done" << endl;
return 0;
}
Output
Main started
Main sleeping
Second thread starting
First thread starting
Second thread done
First thread done
Main done
As explained in this answer, you have to call either join
or detach
on a thread before the std::thread
object is destroyed, otherwise std::terminate
is called.
If you need to use detach
, you will probably want to provide a synchronization mechanism so that the main thread will not end unless all of the detach
'ed threads have finished.
Update
The following code is the same as above except it uses a std::atomic<int>
to wait for the two detached threads to finish before allowing main
to finish.
#include <atomic>
#include <iostream>
#include <thread>
#include <chrono>
using std::cout, std::endl;
using namespace std::chrono_literals;
template<class F>
void create_detached_thread(F&& func) {
std::thread th{std::forward<F>(func)};
th.detach();
}
int main(int argc, const char *argv[]) {
cout << "Main started" << endl;
std::atomic<int> ndone{};
create_detached_thread([&]() {
cout << "First thread starting" << endl;
std::this_thread::sleep_for(400ms);
cout << "First thread done" << endl;
++ndone;
ndone.notify_one();
});
create_detached_thread([&]() {
cout << "Second thread starting" << endl;
std::this_thread::sleep_for(200ms);
cout << "Second thread done" << endl;
++ndone;
ndone.notify_one();
});
cout << "Main sleeping" << endl;
ndone.wait(0);
ndone.wait(1);
cout << "Main done" << endl;
return 0;
}