c++ lambda function calls pure virtual function - c++

I am trying to create a wrapper class for std::thread. This class provides a kick method which starts the thread and calls a pure virtual function. I am using a derived class to call this kick method and derived class also has implemented the virtual function.
class Executor
{
public:
// constructor
Executor();
// destructor
~Executor();
// kick thread execution
void Kick();
private:
// thread execution function
virtual void StartExecution() = 0;
// thread handle
std::thread mThreadHandle;
};
Following is the implementation of executor class
Executor::Executor()
{
// Nothing to be done here
}
Executor::~Executor()
{
if (mThreadHandle.joinable())
mThreadHandle.join();
}
void Executor::Kick()
{
// mThreadHandle = std::thread(&Executor::StartExecution, this);
mThreadHandle = std::thread([this] {this->StartExecution();});
}
I am using a Consumer class which inherits this class and implements StartExecution method. When i use the kick method it shows pure virtual function called and program terminates.
std::unique_ptr<Consumer> consumer = std::make_unique<Consumer>();
consumer->Kick();
In the executor kick method. I added a breakpoint and started looking what is wrong. It comes to the
mThreadHandle = std::thread([this] {this->StartExecution();});
line twice. First because of the kick method, second to execute the lambda function. The first time I see that this points to Consumer class. But when it comes to the lambda function it is messed up and the vptr is pointing to the pure virtual function.
I would be interested in what is wrong in this instead of simple answers.

Just a guess based on what I've tried: your Consumer gets destructed before the thread executes.
I've made ~Executor virtual and added some print statements for relevant function calls.
#include <iostream>
#include <memory>
#include <thread>
#include <chrono>
class Executor
{
public:
// constructor
Executor();
// destructor
virtual ~Executor();
// kick thread execution
void Kick();
private:
// thread execution function
virtual void StartExecution() { std::cout << "Executor::Kick\n"; }
// thread handle
std::thread mThreadHandle;
};
Executor::Executor()
{
// Nothing to be done here
}
Executor::~Executor()
{
std::cout << "~Executor\n";
if (mThreadHandle.joinable())
mThreadHandle.join();
}
void Executor::Kick()
{
// mThreadHandle = std::thread(&Executor::StartExecution, this);
mThreadHandle = std::thread([this] {this->StartExecution();});
}
class Consumer: public Executor {
public:
~Consumer() {
std::cout << "~Consumer\n";
}
private:
virtual void StartExecution() { std::cout << "Consumer::Kick\n"; }
};
int main() {
{
std::cout << "1:\n";
std::unique_ptr<Consumer> consumer = std::make_unique<Consumer>();
consumer->Kick();
}
{
std::cout << "2:\n";
std::unique_ptr<Consumer> consumer = std::make_unique<Consumer>();
consumer->Kick();
std::cout << "Sleeping for a bit\n";
std::this_thread::sleep_for(std::chrono::seconds(1));
}
return 0;
}
Output:
1:
~Consumer
~Executor
Executor::Kick
2:
Sleeping for a bit
Consumer::Kick
~Consumer
~Executor
See it run here
Sleeping before destroying the consumer lets the thread run and call the correct function. A "real" solution would be to ensure that the consumer lives at least as long as the thread itself. Since the thread exists in the base class Executor this isn't guaranteed, as derived classes are destructed before base classes.
From cppreference (emphasis mine):
When a virtual function is called directly or indirectly from a constructor or from a destructor (including during the construction or destruction of the class’s non-static data members, e.g. in a member initializer list), and the object to which the call applies is the object under construction or destruction, the function called is the final overrider in the constructor’s or destructor’s class and not one overriding it in a more-derived class. In other words, during construction or destruction, the more-derived classes do not exist.
This appears to apply when a member function is called in a different thread during construction/destruction.

Thr program goes out of memory even before the thread gets a chance to call the function. If you change your code like this
void Executor::Kick()
{
mThreadHandle = std::thread([this] {this->StartExecution();});
this_thread::sleep_for(chrono::seconds(1)); // any number
}
this will work.
That's the precise reason why you can't pass the this by reference in capture list
Now about your specific question
I would be interested in what is wrong in this instead of simple answers.
The vPTR points to VTable and as the class goes out of the memory, the vPTR points to base class VTable and hence this is happening. you can check the same by printing the vTable address before calling the function

Related

C++ Inheritance and Pointer-To-Member-Functions in combination with threads

currently I'm working on an implementation of a simple HTTP-Webserver (for practise purpose). My class WebServer needs to have a thread to listen for new connections and different threads for reponse handling. I'm not a fan of the way threads are used in C++ so I want to create some abstraction. Therefor I coded the following for easier object-orientated handling with threads (still work in progress)
#include<thread>
#include<chrono>
#include<iostream>
#include "ConnectionListener.h"
class Base {
public:
void start() {
thread = std::thread(&Base::run, this);
}
protected:
virtual void run() = 0;
private:
std::thread thread;
};
class Derived : public Base {
private:
void run() {
while (true) {
std::cout << "Running" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
};
int main() {
Derived d;
d.start();
std::this_thread::sleep_for(std::chrono::seconds(10));
}
This base class should be some sort of interface. The target is, that one can use the start member function of the derived class and have the run member function of the derived class executed in a new thread.
Now my problem / question:
I've learned that one can pass member functions to the thread constructor using pointer-to-member-functions. This is the reason I used &Base::run. But now I'm unsure if the run method of the base class will be executed or the run method of the derived class. My assumption: Due to the fact that we have a pure virtual run function in the base class, the member function of the derived class is used. But: What if the run member function in the base class isn't pure virtual but virtual? Does the execution then depend on the passed object reference (this)?
Hope you can understand what I mean. I'm a bit confused by the concept of pointer-to-member-function in combination with threads and inheritance. The concepts of polymorphism are clear to me. Hope you can help me out.
Greeting,
Tmirror

Passing a virtual member method to thread()

I'm trying to pass a virtual method to the thread class' constructor (C++ thread).
After searching all over, I've only been able to pass a non-virtual member method.
My base class A has a start method as follows:
void A::start() {
thread(&A::runnable,A()); // <--- What do I change here?
}
The function runnable is virtual and is also implemented in derived class B.
I override runnable in derived class B.
I then invoke start on B.
Obviously, and undesirably, the start function uses runnable implemented in A (instead of B) because it is explicitly defined in A::start.
Is there any way to let the runnable function be dynamically bound?
I thought of using templates and a couple of other creative solutions. (I eventually will implement start in B if there are no real solutions)
Any help would be greatly appreciated.
Obviously, and undesirably, the start function uses runnable implemented in A (instead of B) because it is explicitly defined in A::start.
This could be obvious to you, but it is incorrect. When you create a thread you pass an unnamed temporary instance of class A, which obviously has type A so A::runnable would be always called, but you should pass this:
void A::start() {
thread(&A::runnable,this); // <--- What do I change here?
}
Then proper virtual function would be called.
See Boost::Bind and virtual function overloads: why do they work? for details why.
There are a couple of things to address.
First in A::start() you create an anonymous local thread object. Unfortunately, this object will be destructed as soon as you leave A::start(). This will trigger an abort.
When you create a thread object you must always either join() it or detach() it before the object gets destructed.
For the rest of the answer, I'll use a private thread t in A:
class A {
...
protected:
thread t; // default constructed thread object, i.e. without associated thread of execution
public:
...
~A() {
if (t.joinable()) // If thread active and not detached, be sure that it's joined before it is destructed !!
t.join();
}
....
};
Next, in your thread creation, you use A() as parameter. This means that you will create a new anonymous A object and pass it as argument. I guess it's not what you intend to do, so you use this instead.
Then, as was told by Slava, when &A::runnable is used in combination with this, it is the virtual function that is called. So start() should look like:
void start() {
t = move (thread (&A::runnable, this )) ; // Here I create an anonymous thread and move it to t.
}
If your run this code, you'll notice that A::runnable() is called for class A objects and B::runnable() for class B objects.

Initialize boost thread in object constructor?

I want to write a wrapper for boost thread to specialize a threading model. My run() function is going to be a member function of the same class that is using boost::thread as the aggregate thread object. Consider:
class Thread {
public:
Thread(...) : m_thread(&Thread::run, this) {}
private:
void run() { ... }
boost::thread m_thread;
};
This is potentially dangerous because this is not yet fully constructed. However, if I can guarantee that all members of the object used by run() are initialized prior-to initialization of the boost thread, could this actually be considered safe?
The only workaround I can think of that guarantees safety is to have a subclass that guarantees full construction of an object that can be used by the constructor of Thread:
class Thread {
public:
Thread(...) : m_impl(...), m_thread(&ThreadImpl::run, &m_impl) {}
private:
class ThreadImpl {
ThreadImpl(...) { }
void run() { ... }
}
ThreadImpl m_impl;
boost::thread m_thread;
};
Is there a common way to do this? The ThreadImpl class seems like a lot of overhead for such a trivial issue.
The order that members are declared (not the order in the initializer list, though, so be careful) is the order of construction. You should be fine if you declare the thread member last as long as having all members constructed is sufficient to establish a consistent state.
However, if you don't want to rely on that, you can start your thread at the end of the constructor with something like this:
// Constructor
MyThread() {
// Initialize everything else...
boost::thread t(boost::bind(&MyThread::run, this));
m_thread.swap(t);
}
Regarding the safety of using the this pointer, the standard says in 12.6.2:
Note: because the mem-initializer are evaluated in the scope of the
constructor, the this pointer can be used in the expression-list of a
mem-initializer to refer to the object being initialized.
and
Member functions (including virtual member functions, 10.3) can be
called for an object under construction.
You just have to avoid accessing what has not yet been constructed. That can include calling member functions before all base classes have been initialized:
class Derived : public Base {
public:
Derived()
: Base(foo()) // foo() undefined because base class not initialized
{
}
int foo() { return 0; }
};

boost thread destroys polymorphism

duplicate of: "pure virtual method called" when implementing a boost::thread wrapper interface
I am trying to create a more object oriented version of the threads using boost threads.
So I created a Thread class:
class Thread {
public:
Thread() {}
virtual ~Thread() { thisThread->join(); }
void start() { thisThread = new boost::thread(&Thread::run, this); }
virtual void run() {};
private:
boost::thread *thisThread;
};
this class creates the thread in start()
like this:
thisThread = new boost::thread(&Thread::run, this);
The problem is that when I create a class that overwrites the run() method, the run() method from Thread is call by the thread instead of the new run() method
for example I have a class that extends Thread:
class CmdWorker: public Thread {
public:
CmdWorker() : Thread() {}
virtual ~CmdWorker() {}
void run() { /* deosn't get called by the thread */ }
};
when I do
Thread *thread = new CmdWorker();
thread.start(); //---> calls run() from Thread instead of run() from CmdWorker
but just to be more clear:
thread.run(); calls the correct run from CmdWorker, (run() is virtual from Runnable)
Any idea why this happens or how it can be fixed ?
NOTE:
I created a function (that has nothing to do with the Thread class)
void callRun(Thread* thread) {
thread->run();
}
and changed the thread creation to:
thisThread = new boost::thread(callRun, this);
when debugging I noticed that the thread pointer is pointing to a object of type Thread instead of CmdWorker
EDIT:
testcase code at: http://ideone.com/fqMLF
and http://ideone.com/Tmva1
Object seems to be sliced (but this is strange since pointers are used)
didn't manage to add boost to it
The answer is in that question:
"pure virtual method called" when implementing a boost::thread wrapper interface
Basically, when the boost::thread object begins running, the object it was run against had the
time to be deleted.
You have to implement a join method that you call manually before destroying the object.
when debugging I noticed that the thread pointer is pointing to a
object of type Thread instead of CmdWorker
Maybe the CmdWorker object is sliced (i.e. copied by value) into a Thread object somewhere in your code?
Do you get the same behaviour with a minimal test case?
By doing &Thread::Run on a non-virtual function, you are forcing any class that derives from Thread to use the function specified in the Thread base class. Try making Thread::Run a virtual void and see if that fixes your issue.
From reading your updates, you're calling delete in the main thread, while the thread is starting in the other. Depending on the race between the destructor and the invocation of run, it will either:
Crash before it starts, because the vtable is completely destroyed
Call the Thread::run (which is pure virtual, and crashes with a pure virtual thunk)
Call the correct function, which is the derived class run()
If you add a call to sleep(1) after you call start, but before you call delete, you'll find that it works as you expect.

Is it wise to pthead_join() class member-variable thread in the destructor?

I need to make a thread that should run for the duration of the time a class exists. The thread should be destroyed with the class. Would it be wise to code with this general design (join in destructor)? Should I use a detached thread instead possibly?
class A {
public:
A() { pthread_create(m_thread, ...); }
~A() { pthread_join(m_thread, ...); }
private:
pthread_t m_thrad;
};
Lastly, can I use a member function to spawn off the thread, or does it have to be a static or global function?
If you access data from your class A from within the thread then you must join it in the destructor. A detached thread would otherwise access the class data after it has been destroyed which is simply undefined behavior.
Your thread function must be static or global. But you can pass your class' this pointer as arg parameter to pthread_create and static_cast it back in your thread main function and call a normal method on your class. So you have a very slim static function:
class X {
public:
X() {
pthread_create(m_thread, 0, ThreadStart, this);
}
private:
static void *ThreadStart(void *arg) {
static_cast<X *>(arg)->ThreadMain();
return 0;
}
void ThreadMain() {
}
.
.
.
};
I think that it depends on what is the A class about. If you know for sure that the thread will exit some time soon after your instance of the A class dies then I guess you could use detached threads. Otherwise I think you should signal the thread that it should exit and wait for it to do so.