I have the a simple program.
int main()
{
std::atomic<bool> b = true;
ConcurrentQueue<std::string> queue;
std::thread thread( [&]{
while ( b ) {
auto str = queue.wait_and_pop();
std::cout << *str;
}
});
b = false;
queue.push( "end" );
thread.join();
}
ConcurrentQueue<T>
is my own implementation of thread safe queue, wait_and_pop
is a blocking operation that use std::condition_variable
.
this program successfully prints "end" and exits, no problem here. ( there is a bug that b
is false when thread
started which cause it to exit immediately but that is not relevant here )
But if I wrap all these in a class
class object {
public:
object() {
b = true;
thread = std::thread( [this]{
while ( b ) {
auto str = queue.wait_and_pop();
std::cout << *str;
}
});
}
~object() {
b = false;
queue.push( "end" );
thread.join();
}
private:
std::atomic<bool> b;
std::thread thread;
ConcurrentQueue<std::string> queue;
};
and have a function static variable like
object & func() {
static object o;
return o;
}
and main
int main() {
object & o = func();
}
now the program prints "end" then stuck at destructor of o
at line thread.join()
.
I have tested this with clang and no problem. This seem to only happen in VC11. Why is that?
There recently was a thread with the same problem, but I can't find it anymore.
Basically, there's a deadlock in VS's runtime library when you have a static lifetime object that tries to end a thread in its destructor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With