C++ Which thread calls the destructor - c++

If I create a thread_local object, its destructor is called on the thread it was created on:
#include <iostream>
#include <thread>
#include <chrono>
struct MyStruct {
~MyStruct() {
std::cout << "Destructed on thread #" << std::this_thread::get_id() << std::endl;
}
};
void f() {
thread_local MyStruct myStruct;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
int main() {
std::thread t(f);
std::cout << "Created thread #" << t.get_id() << std::endl;
t.join();
}
Created thread #16920
Destructed on thread #16920
Does the C++ standard guarantee this behaviour? It only states this:
A variable with thread storage duration shall be initialized before
its first odr-use (6.2) and, if constructed, shall be destroyed on
thread exit.

Related

How do I make a seperate thread inside a class?

I have a class foo and i put inside a member function a thread object. And i tried to initialize it like this std::thread mythread(&foo::myprint, this); inside another function. My problem is that I get the same thread::get_id with a different function foo::mycount that i need to count something. Both myprint and mycount uses this_thread::sleep_for but they don't sleep separately (something that i want to happen). I follow you up with some code example
class foo
{
void func()
{
std::thread mythread(&foo::myprint, this);
mythread.join();
}
void myprint()
{
sleep_for(1s);
cout << count << endl;
}
void mycount()
{
sleep_for(1ms);
count++;
cout << count << endl;
}
};
void main()
{
foo obj;
while(1)
{
obj.func();
obj.mycount();
}
}
I also tried putting mycount in another function with a thread object, and I don't if std::call_once affected anything, cause i used it inside the mycount function. I expected a different get_id for different functions.
Here is an example with a lambda function to start an asynchronous process.
And using std::future for synchronizing the destructor of your class with the background thread (which is counting numbers in this example).
#include <iostream>
#include <future>
#include <thread>
#include <chrono>
// dont do "using namespace std"
using namespace std::chrono_literals;
class foo
{
public:
foo() = default;
~foo()
{
// destructor of m_future will synchronize destruction with execution of the thread (waits for it to finish)
}
void func()
{
m_future = std::async(std::launch::async, [=] { myprint(); });
}
void myprint()
{
for (std::size_t n = 0; n < 5; ++n)
{
std::this_thread::sleep_for(1s);
std::cout << n << " ";
}
std::cout << "\n";
}
private:
std::future<void> m_future;
};
int main()
{
foo obj;
obj.func(); // start thread
return 0;
}

Destruction of thread_local objects

In the question Using QSqlQuery from multiple threads there was the outcome that thread storage solves the problem.
I made a simple demo code to be absolutely clear about C++11 thread_local specifier. The code below creates two threads which have ThreadLocal object as a local unique object. The Storage::get function is a thread specific singleton. Does the standard guarantee that ThreadLocal destructor is called on join or the exit of the thread function?
Compiled with GCC 5.4.0
(g++ -o main main.cpp --std=c++11 -lpthread)
#include <thread>
#include <mutex>
#include <string>
#include <chrono>
#include <iostream>
#include <atomic>
static std::mutex mtx;
struct ThreadLocal {
std::string name;
~ThreadLocal() {
mtx.lock();
std::cout << "destroy " << name << std::endl;
mtx.unlock();
}
};
struct Storage {
static ThreadLocal &get() {
/* Thread local singleton */
static thread_local ThreadLocal l;
static std::atomic<int> cnt(0);
l.name = std::to_string(cnt);
cnt++;
return l;
}
};
void thread() {
mtx.lock();
std::cout << Storage::get().name << std::endl;
mtx.unlock();
std::this_thread::sleep_for(std::chrono::seconds(1));
}
int main(int argc, const char **argv) {
std::thread t1(&thread);
std::thread t2(&thread);
t1.join();
t2.join();
}
If the object was constructed, it will be destroyed on the exit of the thread function. Pretty much in those exact words over at [basic.stc.thread]/2:
A variable with thread storage duration shall be initialized before
its first odr-use ([basic.def.odr]) and, if constructed, shall be
destroyed on thread exit.

c++ meyers singleton containing std::thread can't join

i have a problem with the scott meyers singleton. my singleton contains a thread which shall get joined in the singleton destructor, but the join() never returns.
When i join the thread before application exit everything works fine. am i missing something? following my code:
#include <thread>
#include <atomic>
#include <iostream>
#include <chrono>
class Singleton
{
public:
static Singleton& get_instance()
{
static Singleton instance;
return instance;
}
void stop()
{
run = false;
if (t.joinable())
t.join();
}
private:
Singleton() { t = std::thread{ &Singleton::f, this }; }
~Singleton()
{
std::cout << "dtor start" << std::endl;
stop();
std::cout << "dtor end" << std::endl; // <-- never gets called. programm freezes here
}
void f()
{
while (run)
{
// do work ...
std::cout << "i do some work..." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
}
std::atomic<bool> run = true;
std::thread t;
};
int _tmain(int argc, _TCHAR* argv[])
{
auto& s = Singleton::get_instance();
std::this_thread::sleep_for(std::chrono::seconds(2));
s.stop(); // <-- works fine
return 0;
}
So as i mentioned: with the call to s.stop(); it works fine but without it "freezes".
Is there a way to prevent the call to stop() ?

How to join a std::thread from itself (in C++11)

I have a std::thread waiting and reading from a socket. And there is a pointer to this thread stored somewhere. But when something bad happens and the thread ends, I want it to call something that results in a function that will join this thread and then delete the pointer referring to it. (I have access to that pointer from within the thread)
I could do that in another thread but then that new thread becomes the problem.
You could create your thread in a detached state, and make your thread lifetime dependent a condition variable and switch a boolean state on finish.
#include <thread>
#include <iostream>
#include <unistd.h>
#include <condition_variable>
#include <mutex>
class A {
private:
void Threadfunction();
volatile bool class_running;
volatile bool thread_running;
std::condition_variable cv;
std::mutex mu;
public:
A();
~A();
void Stop();
};
A::A(){
class_running = true;
thread_running = false;
std::thread t(&A::Threadfunction,this);
t.detach();
}
A::~A(){
if(class_running) {this->Stop();}
}
void A::Stop() {
std::unique_lock<std::mutex> lk(mu);
class_running = false;
while(thread_running) {
cv.wait(lk);
}
std::cout << "Stop ended " << std::endl;
}
void A::Threadfunction(){
thread_running = true;
std::cout << "thread started " << std::endl;
while(class_running){
// Do something
}
thread_running = false;
cv.notify_one();
std::cout << "thread stopped " << std::endl;
}
int main(){
A a1;
A a2;
sleep(1);
std::cout << "a1.Stop() called " << std::endl;
a1.Stop();
sleep(1);
std::cout << "a2.Stop() not called but a2 goes out of scope and destructor is called " << std::endl;
}
Change your design so that you don't have this bizarre requirement. One simple solution is to use shared_ptrs to a control structure that owns the thread and has other status information as well. The thread can hold a shared_ptr to this control structure and use it to report its status to any other interested code. When nobody cares about this thread anymore, the last shared_ptr to this control structure will go away and it will be destroyed.

Non-local object with thread storage duration

It is unclear why does object with thread storage duration is not default-initialized? For instance:
#include <iostream>
using std::cout;
struct S
{
S(){ cout << "S\n"; }
~S(){ cout << "~S\n"; }
};
thread_local S s;
int main()
{
}
IdeOne
stdout is empty. But I expected that stdout would contain
S
~S
It is because sec. 8.5/12 N3797:
If no initializer is specified for an object, the object is
default-initialized
This does not say anything about storage duration of the object.