multithreading - C++ Inheritance : Calling virtual method when it has been overridden -
i trying build service
object can run (i.e. execute it's run()
function) in separate thread. service object
#include <boost/noncopyable.hpp> #include <atomic> #include <thread> #include <iostream> class service : public boost::noncopyable { public: service() : stop_(false), started_(false) { } virtual ~service() { stop(); if (thread_.joinable()) { thread_.join(); } } virtual void stop() { stop_ = true; } virtual void start() { if (started_.load() == false) { started_ = true; thread_ = std::thread([&] () { run(); }); } } protected: virtual void run() = 0; std::atomic<bool> stop_; std::atomic<bool> started_; std::thread thread_; };
i creating test
class inherits abstract class , called in main()
function
class test : public service { public: test() : service() { std::cout<< "ctor" << std::endl; start(); } ~test() { std::cout<< "dtor" << std::endl; } protected: void run() override { std::cout << "hello world" <<std::endl; } }; int main() { test test1; return 0; }
now when execute this, why error saying pure virtual function called
? run()
function overridden in test
class. whats worse runs correctly sometimes?
$ ./a.out ctor dtor pure virtual method called terminate called without active exception $ ./a.out ctor dtor pure virtual method called terminate called without active exception $ ./a.out ctor dtor pure virtual method called terminate called without active exception $ ./a.out ctor dtor hello world $ ./a.out ctor dtor pure virtual method called terminate called without active exception
what going wrong here?
follow along, step step:
1) construct object.
2) execute following piece of code:
if (started_.load() == false) { started_ = true; thread_ = std::thread([&] () { run(); }); }
the parent thread returns main()
immediately exits , destroys object.
here's bug:
- you not guaranteed thread started in
start()
going reach callrun()
, above, before parent thread terminates process. both child thread, , parent thread runs concurrently.
so, every once in while, parent thread destroy object before child thread gets in gear, , calls run
().
at point, object run
() method gets invoked, destroyed.
undefined behavior.
the assertion you're hitting, every once in while, 1 possible result of undefined behavior.
Comments
Post a Comment