Reputation: 435
The below code blows up during run time but works fine during debug. I cant understand why. I am joining the thread in destructor as required.
Could some one help ?
surprisingly the code works fine during debug.
Tried couple of times in debug and every time seems fine.
#include<iostream>
#include<string>
#include<thread>
#include<memory>
using namespace std;
template<typename T> class Runnable
{
private:
std::thread t;
void runImpl()
{
static_cast<T*>(this)->run();
}
public:
virtual void run() = 0;
void start()
{
this->t = std::thread(&Runnable::runImpl, this);
}
~Runnable()
{
std::cout << "I am in the destructor of the base class" << std::endl;
if(t.joinable())
{
std::cout << "joinable" << std::endl;
t.join();
}
else
std::cout << "not joinable" << std::endl;
}
};
class HelloWorld : public Runnable<HelloWorld>
{
public:
void run()
{
std::cout << "I am in thread id = " << std::this_thread::get_id() << " and the message is : HelloWorld How are you" << std::endl;
}
};
int main(int argc, char* argv[])
{
std::cout << "I am in the main thread id = " << std::this_thread::get_id() << std::endl;
{
HelloWorld item;
item.start();
}
return(0);
}
Upvotes: 1
Views: 210
Reputation: 52471
You have a race on *this
, between the worker thread calling a virtual member function, and the main thread entering the destructor. This exhibits undefined behavior.
Practically speaking, the vtable pointer may already have been updated to that of Runnable
, and the thread ends up calling a pure virtual function.
Upvotes: 4