Object slicing with Queues - c++

Developing on Ubuntu using Eclipse/gcc with -std=c++0x.
I seem to be having an issue with object slicing, that doesn't fall under the other questions I've seen here. I have a very simple base class / child class inheritance model. Base class has one pure virtual function which obviously the child implements:
class Parent{
public:
Parent();
virtual ~Parent();
virtual void DoStuff() = 0;
};
class Child : public Parent{
public:
Child();
virtual ~Child();
virtual void DoStuff(); //Child can have "grandchildren"
};
What I want is to have a queue where I can store these objects for processing by a worker thread. I know I should be storing pointers, or else I'd guarantee slicing. So, in the class ("Processor") which does this I have:
typedef queue<Parent*> MYQUEUE; //#include <queue>
static MYQUEUE myQueue;
//Call this after creating "Child c;" and passing in &c:
void Processor::Enqueue(Parent* p)
{
myQueue.push(p);
}
void* Process(void* args) //function that becomes the worker thread
{
while(true)
{
if(!myQueue.empty())
{
Parent* p = myQueue.front();
p->DoStuff();
myQueue.pop();
}
}
return 0;
}
What then happens is that the program crashes, saying "pure virtual method called", as if the inheritance/polymorphism isn't working correctly. I know the inheritance is set up correctly, because as I test I confirmed this works:
Child c;
Parent* p = &c;
p->DoStuff();
Any guidance greatly appreciated!

If you are passing the object to a worker thread, you can't create it on the stack. By the time the worker thread invokes it, the parent thread has likely left that function and destroyed the object. You need to dynamically allocate (perhaps via new) it in the parent thread and only free (delete) it in the worker thread after you're done with it.
As another note, you need locking around your queue accesses if the parent is able to enqueue a job while the worker is running.

The error means that the object pointed to by p at the point of the call has type Parent. How it got that way depends on the code that you haven't shown.

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

c++ lambda function calls pure virtual function

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

Synchronize at most derived destructor

I encountered a crash from calling a pure virtual method, due to a race condition where other threads are still calling methods of a derived class when it's already destroyed. Here's the gist of it:
class Resource
{
protected:
Resource();
virtual ~Resource();
public:
virtual void *lock_shared() = 0;
virtual void unlock_shared() = 0;
// Wait for all other threads to finish.
void sync()
{
mutex.lock();
mutex.unlock();
}
protected:
std::shared_mutex mutex;
};
Resource::~Resource()
{
sync();
}
class Image : public Resource
{
public:
Image();
~Image() override;
void *lock_shared() override
{
mutex.lock_shared();
return accessData();
}
void unlock_shared() override
{
processData();
mutex.unlock_shared();
}
};
Note that when an object of type Image gets destroyed, the intention is to wait for all threads with shared access to finish. However, due to the C++ destructor calling order, Image::~Image() is done by the time we sync() in Resource::~Resource, meaning the object is no longer of type Image, and we can't call any of Image's methods. Other threads still holding a lock will however try to call Image::unlock() when they're done, resulting in a pure virtual call to Resource::unlock() and aborting the program.
The apparent solution is simple: call sync() in Image::~Image() instead.
Unfortunately this is very prone to happening again whenever I derive a new class from Resource, or, from Image. I've added an assert() to Resource::~Resource() to check that try_lock() is always successful, but that doesn't help when I derive from Image.
So I was wondering if anyone knows a more foolproof way to prevent this race condition once and for all. Thanks.
As an idea, if you are ok with using some factory for creating objects of classes derived from Resource rather than explicitly create them, you can make this factory return std::unique_ptr<DerivedResource> with custom deleter which would call p_obj->sync() before actually deleting an owned instance of p_obj.

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.