In his book (The C++ Programming Language, Chapter 42.2.5), Bjarne Stroustrup discourages from using detach
if you don't have to and gives several reasons for that.
See also here: https://stackoverflow.com/a/22804813/5717589.
The consequence in this case is that the destructor of the Server trapped in the thread is not executed, cleanup()
doesn't run.
I wrote the following code to see what's happening there:
#include <iostream>
#include <thread>
#include <unistd.h> // for linux usleep
using namespace std;
static bool needed; // tells the server if we need it
class Server {
public:
Server () : id (0){
++id;
cout << "Server " << id << " started. Work status: " << work_done << endl;
}
Server (const Server & rhs) : id (rhs.id){
++id;
cout << "Server " << id << " started by copy. Work status: " << work_done << endl;
}
Server (Server && rhs) : id (rhs.id) {
++id;
cout << "Server " << id << " started by move. Work status: " << work_done << endl;
}
void operator()() {
cout << "Hi! Doing work..." << endl;
work_done = true;
while (needed) {
usleep(300000);
cout << "sleeping... Work status: " << work_done << endl;
}
}
~Server() {
cout << "Server " << id << " stopping. Work status: " << work_done << endl;
if (work_done)
cout << "Cleanup triggered by Server " << id << endl;
}
bool work_done {false};
int id;
};
int main() {
needed = true;
Server s;
// thread t(s);
thread t(std::move(s));
// t.detach();
usleep(1000000);
needed = false;
t.join();
cout << "end" << endl;
}
The output is:
Server 1 started. Work status: 0
Server 2 started by move. Work status: 0
Server 3 started by move. Work status: 0
Server 2 stopping. Work status: 0
Hi! Doing work...
sleeping... Work status: 1
sleeping... Work status: 1
sleeping... Work status: 1
sleeping... Work status: 1
Server 3 stopping. Work status: 1
Cleanup triggered by Server 3
end
Server 1 stopping. Work status: 0
With t.detach()
on and t.join()
off the result is:
Server 1 started. Work status: 0
Server 2 started by move. Work status: 0
Server 3 started by move. Work status: 0
Server 2 stopping. Work status: 0
Hi! Doing work...
sleeping... Work status: 1
sleeping... Work status: 1
sleeping... Work status: 1
end
Server 1 stopping. Work status: 0
(What puzzles me is some temporary instance, Server 2, which appears both with move and copy.)