During runtime I get the error message: "pure vitual function called".
QThreadpool seems to call the pure virtual void run() of the parent class QRunnable, instead off void run() in the derived class Bm.
Strangely enough the if I ry to call the function manually with b_1.run();, there is no problem during runtime.
Here is my class implentation:
class Bm : public QRunnable
{
public:
void run()
{
test();
}
private:
void test();
};
Here is my main function where the error happens.
int main()
{
QThreadPool pool;
pool.setMaxThreadCount(1);
BM b_1;
pool.start(&b_1);
return 0;
}
My Question: Why doesnt Qthreadpool use Bm::run() over QRunnble::run()?
The thread objects gets deleted when going out of the main() function scope even before the QThreadPool calls IRunnable::run(). Using QThreadPool::waitForDone() before returning will assure the thread being executed.
Related
I have some code that is to run on Linux (x86_64) and Raspberry Pi. The code runs ok on Linux, but crashes with a SIGSEGV on RPi. A derived method appears to not have the vtable populated and I wonder whether it is as a result of a race condition?
Here are the classes that implement the threading:
class Runnable {
public:
Runnable() {}
virtual ~Runnable() {}
// Starts the thread & execute the doWork() method.
void start() {
thread = std::thread(&Runnable::doWork, this);
}
// Stop the thread if running
virtual void stop() = 0;
// Joins the thread, blocks until the thread has finished.
void join() {
if (thread.joinable()) { thread.join(); }
}
protected:
std::thread thread; ///< the thread used by this class
/**
* #brief The method that does work. This will be called when the thread is started.
* The implementation should not return until stop() is called (or is finished with work).
* This is in protected scope as it should not be called except from the start() method.
*/
virtual void doWork() = 0;
};
template <typename VIRTUAL_CLASS_TYPE>
class SomeRunner : public Runnable {
public:
SomeRunner() {}
virtual ~SomeRunner() {
// do not delete classPtr, as a framework we are using deletes it for us
}
virtual void doWork() {
// do some work
classPtr = new VIRTUAL_CLASS_TYPE();
// notify main thread that we have created classPtr
// this is done via a condition variable & mutex
notifyIsReady();
// do some more work
}
virtual void stop() {
// tell thread to stop work
}
VIRTUAL_CLASS_TYPE *getClassPtr() {
return classPtr;
}
protected:
VIRTUAL_CLASS_TYPE *classPtr = nullptr;
}
// Within InterfaceLibrary.a
class BaseClass {
public:
BaseClass() {}
virtual ~BaseClass() {}
virtual void someMethod() = 0;
}
//Within ImplementationLibrary.a:
class ImplClass : public BaseClass {
public:
ImplClass() : BaseClass() {}
virtual ~ImplClass() {}
virtual void someMethod() {
// do something here
}
}
// within main application project
class ClassThatCausesDump {
// ...
void someMethod(BaseClass *bc) {
bc->someMethod();
}
}
bool isReady = false;
std::mutex mutexIsReady;
std::condition_variable cvIsReady;
void notifyGlsIsReady() {
std::unique_lock<std::mutex> lock(mutexIsReady);
isReady = true;
lock();
cvIsReady.notify_one();
}
int main(int argc, char **argv) {
// ...
SomeRunner<ImplClass> runner;
runner.start();
// main blocks until notified that the ImplClass has been created by runner
std::unique_lock<std::mutex> isReadyLock(mutexIsReady);
cvIsReady.wait(isReadyLock, [] {return isReady;});
ClassThatCausesDump dump;
dump.someMethod(runner.getClassPtr()); // this triggers the core dump on RPi
The variable classPtr, although passed as a BaseClass should call the derived someMethod(). However, when I run using gdb, I see that the program crashes at the call to someMethod() within ClassThatCausesDump. It tries to execute an instruction at 0x000000.
The program works on a Linux VM within a powerful multicore OSX machine, but not on RPi. I cleaned everything then recompiled, then it worked suddenly on RPi. Then I cleaned again to make sure it wasn't a fluke, then it went back to crashing (it never crashes on Linux). That makes me think there's perhaps something funny about the way the class is created in a separate thread perhaps?
Any ideas, please?
EDIT:
I don't think this is an issue to do with threading, because a call to the offending virtual function is ok if done within the doWork() method.
virtual void doWork() {
// do some work
classPtr = new VIRTUAL_CLASS_TYPE();
VIRTUAL_CLASS_TYPE *ptr = getClassPtr();
ptr->someMethod(); // this is ok and does not crash
// This next line is only here for testing because we know that VIRTUAL_CLASS_TYPE is of type ImplClass!
BaseClass *bc = (BaseClass*)ptr;
bc->someMethod(); // this crashes
// notify main thread that we have created classPtr
// this is done via a condition variable & mutex
notifyIsReady();
// do some more work
}
Hi I have the following C++ code,
I have MyThread class in the thread.h file
class MyThread
{
public:
void start();
virtual void* task() = 0;
};
I have worker class in the worker.h file
class Worker : public MyThread
{
virtual ~Worker();
virtual void* task(); // I have implementation in worker.cpp
};
Have used pthread_create() in the start() in thread.cpp file for creating a thread and I want to make the task() routine defined in the worker.cpp as the start routine . So how can I do that ? What should I pass as the parameter to the start routine in pthread_create ?
I have tried this but it gives an error:
pthread_create(&(this->threadId),&(this->attr),(void *)task,NULL);
You can't use member function as a thread function. You can only use free functions or static member functions, but you can pass arbitrary void* argument to that function and you can pass pointer to this as that argument, that allows you to call member function inside that function:
class MyThread
{
public:
void start();
virtual void* task() = 0;
static void * thread_routine(void* pthis)
{
MyThread* t = static_cast<MyThread*>(pthis);
t->task();
return 0;
}
};
Then you launch your thread like this
void MyThread::start()
{
pthread_create(&(this->threadId),&(this->attr),thread_routine, this);
}
You can't use task() as start routine for the thread because it is a member function instead of a free function, like the expected signature void *(*start_routine)(void*). (also, it doesn't have the pointer to void parameter)
I would just create a wrapper and have it as the start routine, something like this:
void *wrapper(void *data)
{
Worker worker;
worker.task();
}
I have a class that has a Start method to start a thread that executes the virtual ThreadFunction at a predefined interval. The Stop method sets an event and waits until the the thread terminates (by a WaitForSingleObject on the thread handle).
In the destructor of MyThread, I call the Stop method. So whenever I delete the instance, I'm sure the thread is stopped before the delete returns.
class MyThread
{
void Start();
void Stop();
~MyThread() { Stop(); }
virtual VOID ThreadFunction() { }
};
Next I have a class that derives from MyThread:
class A : MyThread
{
virtual VOID ThreadFunction()
{
for (int i = 0; i < 1000; i++)
TestFunction();
}
void TestFunction() { // Do something }
};
Consider this code:
A a = new A();
a->Start();
delete a;
The problem is that delete a will first call the destructor of A before it will call the destructor of MyThread right? So if the thread was executing the for-loop in the ThreadFunction, the Stop method will be called after a has been destructed. This can lead to an access violation, when ThreadFunction calls TestFunction on a destructed instance.
A solution would be to add a destructor to class A that calls the Stop method, like this:
class A : MyThread
{
~A()
{
Stop();
}
}
But because I have a more complex class hiërarchy, that involves multiple inherited classes, this would mean I have to call the Stop method in each destructor, which would result in the Stop method being called plenty of times for only one instance that needs to be deleted.
Is there any other way to tackle this problem?
Your destructor in MyThread should be defined as 'virtual'.
class A{
public:
A(){cout<<"A"<<endl;}
virtual ~A(){cout<<"~A"<<endl;}
};
class B : public A{
public:
B(){cout<<"B"<<endl;}
~B(){cout<<"~B"<<endl;}
};
int main(){
A* b = new B();
cout<<"do something"<<endl;
delete b;
b = NULL;
return 0;
}
The result is:
A
B
do something
~B
~A
and when it doesn't use virtual, The result is:
A
B
do something
~A
As Rolle and R. Martinho Fernandes suggested, I needed to separate the two concerns.
class MyThread should not start or stop itself as its responsibility should be limited to the code it executes and not to the lifetime of the thread.
So the solution was to stop the thread from an other class (the same class that started the thread) which is responsible for the lifetime of the thread.
I'm trying to use std::thread from C++11. I couldn't find anywhere if it is possible to have a std::thread inside a class executing one of its function members. Consider the example below...
In my try (below), the function is run().
I compile with gcc-4.4 with -std=c++0x flag.
#ifndef RUNNABLE_H
#define RUNNABLE_H
#include <thread>
class Runnable
{
public:
Runnable() : m_stop(false) {m_thread = std::thread(Runnable::run,this); }
virtual ~Runnable() { stop(); }
void stop() { m_stop = false; m_thread.join(); }
protected:
virtual void run() = 0;
bool m_stop;
private:
std::thread m_thread;
};
class myThread : public Runnable{
protected:
void run() { while(!m_stop){ /* do something... */ }; }
};
#endif // RUNNABLE_H
I'm getting this error and others: (same error with and without the $this)
Runnable.h|9|error: no matching function for call to ‘std::thread::thread(<unresolved overloaded function type>, Runnable* const)’|
When passing a pointer.
Runnable.h|9|error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say ‘&Runnable::run’|
Here's some code to mull over:
#ifndef RUNNABLE_H
#define RUNNABLE_H
#include <atomic>
#include <thread>
class Runnable
{
public:
Runnable() : m_stop(), m_thread() { }
virtual ~Runnable() { try { stop(); } catch(...) { /*??*/ } }
Runnable(Runnable const&) = delete;
Runnable& operator =(Runnable const&) = delete;
void stop() { m_stop = true; m_thread.join(); }
void start() { m_thread = std::thread(&Runnable::run, this); }
protected:
virtual void run() = 0;
std::atomic<bool> m_stop;
private:
std::thread m_thread;
};
class myThread : public Runnable
{
protected:
void run() { while (!m_stop) { /* do something... */ }; }
};
#endif // RUNNABLE_H
Some notes:
Declaring m_stop as a simple bool as you were is horribly insufficient; read up on memory barriers
std::thread::join can throw so calling it without a try..catch from a destructor is reckless
std::thread and std::atomic<> are non-copyable, so Runnable should be marked as such, if for no other reason than to avoid C4512 warnings with VC++
That approach is wrong.
The problem is that while the object is still under construction its type is still not the most derived type, but the type of the constructor that is executing. That means that when you start the thread the object is still a Runnable and the call to run() can be dispatched to Runnable::run(), which is pure virtual, and that in turn will cause undefined behavior.
Even worse, you might run into a false sense of security, as it might be the case that under some circumstances the thread that is being started might take long enough for the current thread to complete the Runnable constructor, and enter the myThread object, in which case the new thread will execute the correct method, but change the system where you execute the program (different number of cores, or the load of the system, or any other unrelated circumstance) and the program will crash in production.
I'm very new to c++, but I think I understand what is going on. The parent class is trying to call the pure virtual member function in the parent class. I thought that by overriding the virtual function in the child class, it would be called instead.
What am I doing wrong?
Provided for me in parent.h
class Parent
{
public:
virtual void run() = 0;
protected:
/** The function to starter routine and it will call run() defined by the
* appropriate child class.
* #param arg Arguments for the starter function
*/
static void * init (void * arg);
};
I'm trying to do this in parent.cpp
void * Parent::init(void * arg)
{
run();
}
In my child.h I have this:
class Child : public Parent
{public:
//...
virtual void run();
//...
};
And in child.cpp I have:
void Child::run()
{
sleep(10);
}
The function init in parent.cpp is where this fails to compile. How do I call a derived function from the parent class? All my googleing has only turned up notes about not calling virtual functions in the child's constructor.
Any help at all would be appreciated.
run() is an instance member. Parent::init is a static (class-level) member. So in your init() implementation, there is no instance (of Parent or Child) available on which to call run().
You're trying to call an instance method from a static method. You'll need to change init() to be an instance method (by removing the static keyword) or else you'll need to call the run() method using an object, e.g. obj->run() or obj.run().
Do you know the actual type of arg: is it in fact a Parent instance? If so, then ...
void Parent::init(void* arg)
{
Parent* self = static_cast<Parent*>(arg);
self->run();
}
Look at this example that I recently provided here:
/** calls thread_func in a new thread passing it user_data as argument */
thrd_hdl c_api_thread_start(void (*thread_func)(void*), void* user_data);
/** abstract thread base class
* override my_thread::run to do work in another thread
*/
class my_thread {
public:
my_thread() hdl_(c_api_thread_start(my_thread::thread_runner,this)) {}
// ...
private:
virtual int run() = 0; // we don't want this to be called from others
thrd_hdl_t hdl_; // whatever the C threading API uses as a thread handle
static int thread_runner(void* user_data)
{
my_thread* that = reinterpret_cast<my_thread*>(user_data);
try {
return that->run();
} catch(...) {
return oh_my_an_unknown_error;
}
}
};