c++ - Is it safe to wait for asynchronous work by joining in the destructor? -
suppose have class may run code asynchronously, , asynchronous code uses class instance things call member functions, read data members, etc. class instance must outlive background thread in order accesses safe. sufficient ensure joining background thread in destructor? example:
#include <iostream> #include <thread> class foo final { public: foo() = default; void bar() { std::cout << "hopefully there's nothing wrong using " << << "\n"; } void bar_async() { if (!m_thread.joinable()) { m_thread = std::thread{&foo::bar, this}; } } ~foo() { if (m_thread.joinable()) { std::cout << "waiting " << m_thread.get_id() << "\n"; m_thread.join(); } } private: std::thread m_thread; }; int main() { foo f; f.bar_async(); } specifically, i'm worried object lifetime rules:
for object of class types destructor not trivial, lifetime ends when execution of destructor begins.
... after lifetime of object has ended , before storage object occupied reused or released, following uses of glvalue expression identifies object undefined: ...
- access non-static data member or call non-static member function.
but me, strict reading of above imply calling this->bar() inside ~foo() directly undefined, "obviously" not case.
cppreference right talking accessing members object, not inside destructor. if @ [class.cdtor]/1 see that
for object non-trivial constructor, referring non-static member or base class of object before constructor begins execution results in undefined behavior. object non-trivial destructor, referring non-static member or base class of object after destructor finishes execution results in undefined behavior.
emphasis mine
so, long in destructor can still work member objects not destroyed until scope of destructor ends.
so, calling join on thread fine here. if think if wasn't things lock guards useless if accessing mutex refer undefined behavior.
Comments
Post a Comment