Reputation: 449
This is a continuation to my question: Thread creation inside constructor
Now that I have successfully created a thread in a constructor, I know that it must be joined. As I am developing an API, I have no control over the main function so I can't join it there.
Will it be right to join the thread in the class destructor, considering that the instanced object of that class would have an application's lifetime?
Upvotes: 6
Views: 10420
Reputation: 2720
I have come up with a threading pattern that I have found handles all of the weird situations in C++ regarding running threads in classes.
http://chrisd.nl/blog/how-to-run-threads/
Upvotes: 1
Reputation: 62777
You have encountered the one of the shortcomings of C++ RAII: Destructors can't easily report errors, and a destructors can't fail gracefully, because they have no return value and throwing exceptions is bad idea.
So if the other thread is not responding to a request to stop, what can destructor do? It can wait more or violently destroy the other thread or leave it running, none of which are very nice options. And then it can either ignore the situation, just log it, or throw an exception despite the risk of application terminating immediately, again not a very nice set of options.
So, you have at least 3 options
With threads, a thread failing to terminate promptly can often be considered a programming error comparable to a segfault, so you could choose to terminate the application with helpful (to the developer) diagnostic message (2nd bullet point above), or just let the program hang (1st bullet point above). But this is a bit risky, because if down the road you need to create a thread which can't terminate quickly (it is doing a blocking system call, or it must notify the other end of a network connection, which may be slow), and it's a good idea to think how to solve this before locking down a design.
Upvotes: 2
Reputation: 76297
You could do that. However, are you really interested in the mechanism of launching a new thread, or are you perhaps interested in the effect of performing something asynchronously? If it's the latter, you can move to the higher level async
mechanism:
#include <iostream>
#include <future>
void bar()
{
std::cout << "I'm bar" << std::endl;
}
class foo
{
public:
foo() :
m_f(std::async(
std::launch::async,
bar))
{
}
~foo()
{
m_f.get();
}
private:
std::future<void> m_f;
};
int main ()
{
foo f;
}
You're asking in the constructor to launch bar
asynchronously. You don't care about managing the thread yourself - let the library handle that.
Place the resulting future
in a member.
In the dtor, get
the future.
Upvotes: 8
Reputation: 215
Sure, you could do. just make sure the thread will exist otherwise your program will hang forever on that join.
Upvotes: 1