Using C++11 thread with pure virtual thread function - c++

I have code where objects that are intended to execute in separate thread derive from a base class with a pure virtual Run function. I cannot get the following (simplified test code) to run the new thread.
#include <iostream>
#include <thread>
#include <functional>
class Base {
public:
virtual void Run() = 0;
void operator()() { Run(); }
};
class Derived : public Base {
public:
void Run() { std::cout << "Hello" << std::endl; }
};
void ThreadTest(Base& aBase) {
std::thread t(std::ref(aBase));
t.join();
}
int main(/*blah*/) {
Base* b = new Derived();
ThreadTest(*b);
}
The code compiles fine (which is half the battle) but "Hello" never gets printed. If I was doing something wrong I'd expect a runtime error at some point.
I'm using gcc.
Edit: The code above fails to compile on VS2012, with:
error C2064: term does not evaluate to a function taking 0 arguments
You need to use a lambda instead of std::ref, i.e.
void ThreadTest(Base& aBase)
{
std::thread t([&] ()
{
aBase.Run();
});
t.join();
}

You need to add -pthread to g++ command line, as explained in this answer to a similar question: https://stackoverflow.com/a/6485728/39622.

Related

Guarding against vtable data race in derived destructor

Suppose I have the following code
#include <thread>
#include <iostream>
#include <atomic>
struct FooBase {
void start(){
run_condition_ = true;
t_ = std::thread([this](){
thread_handler();
});
}
virtual ~FooBase(){
run_condition_ = false;
if(t_.joinable())
t_.join();
}
protected:
virtual void thread_handler() = 0;
std::atomic_bool run_condition_{false};
private:
std::thread t_;
};
struct Foo : FooBase {
void thread_handler() override {
while(run_condition_){
std::cout << "Foo derived thread.." << std::endl;
}
}
};
int main(){
Foo f;
f.start();
getchar();
return 0;
}
Here I think because the destructor of the derived class Foo is called before FooBase the thread_handler vtable lookup happens in the base class IF the thread has not yet joined (still running) when the destructor of Foo is done. Since FooBase::thread_handler is pure virtual I am essentially guranteed a sigabort.
How do I guard against this? I hack my way through by not having thread_handler as pure virtual
virtual void thread_handler(){}
But I am lost as to how I can guard against this in the baseclass itself, I can implement a join_thread interface in the base class and call this from every derived class, but this seems cumbersome.
There's two issues here, neither of which match precisely what you described.
Your thread only gets stopped in ~FooBase(). This means that if Foo::thread_handler ever reads or writes to any of its members, they will get destroyed out from under it before the thread is stopped.
It you get to the destructor fast enough, it's possible that start() won't have actually invoked thread_handler() on the new thread by the time Foo gets destroyed - which will lead to the pure virtual call.
Either way, you need to ensure that by the time Foo is destroyed, anything related to thread_handler is done. This implies that every derived class from FooBase has to have, in its destructor:
run_condition_ = false;
if (t_.joinable()) {
t_join();
}
Setting aside that this directly doesn't work because t_ is private (you could wrap that into a protected stop()), it's an awkward design if all of your derived classes need to do something special just to work. You could instead put FooBase into its own class that just takes an arbitrary callable as an argument:
class joining_thread {
public:
joining_thread() = default;
~joining_thread() { stop(); }
bool running() const { return run_condition_.load(); }
template <typename... Args>
void start(Args&&... args) {
run_condition_ = true;
t_ = std::thread(std::forward<Args>(args)...);
}
void stop() {
run_condition_ = false;
if (t_.joinable()) t_.join();
}
private:
std::thread t_;
std::atomic_bool run_condition_{false};
};
And then your Foo can just have that as a member:
class Foo {
public:
void start() {
t_.start([this]{
while (t_.running()) { ... }
});
}
private:
// just make me the last member, so it's destroyed first
joining_thread t_;
};
That's still a little awkward with the whole running() thing, but hopefully the idea makes sense.
What you describe is not possible. You call "start" after you have constructed the object. The object is at that stage valid. You have avoided the common problem of calling a virtual function in the constructor, which would have caused issues. There is something called a memory barrier that is implied by any thread calls, so you can count on the fact the new thread will start with a view of memory that existed at the point it was created. Any thing that existed AND was not changed, is fine.
Your problem (as described in another answer) is that you can exit and destroy the object (and it's vtable), before the thread is complete.
The simplest fix for this is use a packaged task. Calling "get" on the future ensures the task is finished before you continue. Consider the code below
#include "stdafx.h"
#include <thread>
#include <iostream>
#include <atomic>
#include <future>
int main()
{
std::atomic<bool> stop{ false };
std::future<void> sync;
std::packaged_task<void()> task([&stop]()
{
while (!stop)
{
std::cout << "Running\n";
}
});
std::thread thread([&task]() {task();});
getchar();
stop = true;
task.get_future().get();
thread.join();
return 0;
}

Start thread with derived class's member function

Similar to this question: Start thread with member function and this one: std::thread calling method of class
However I have the following:
#include <thread>
#include <iostream>
class myAbstractClass {
public:
virtual void myFunction() = 0;//abstract class
}
class myFirstClass : public myAbstractClass {
public:
void myFunction() { std::cout << "First class here";}
}
class mySecondClass : public myAbstractClass {
public:
void myFunction() { std::cout << "Second class here";}
}
Then I have to call myFunction() from a different place in a new thread, but the following does not compile (and I can't think of anything else to try):
public void callMemberFunctionInThread(myAbstractClass& myInstance) {
std::thread myThread (&myAbstractClass::myFunction, myInstance);
//supposed to call myInstance.myFunction() on myThread
}
Pass std::ref(myInstance). Note that std::thread constructor will make a copy of the arguments passed to it (see here), and you can't copy a myAbstractClass.
(Then, all of this will still work because std::thread functionality is described in terms of std::invoke, which unwraps the std::reference_wrapper obtained by std::ref and calls the pointer to member function onto it. See here).

Variables defined in if-cases leak? (aka why does this even compile?)

It seem that variables declared inside an if-statement leaks to the following statement?
I copy-pasted some code and to my surprise it compiled, when it shouldn't have!
I was about to commit the code and lucily I caught the error before that. Below here is a working (?) program that shows the problem.
The following code snippet calls a function on an object that doesn't exist:
#include <iostream>
class A {
public:
virtual ~A() {}
};
class B : public A {
public:
void fooB() { std::cout << "fooB\n"; }
};
class C : public A {
public:
void fooC() { std::cout << "fooC\n"; }
};
int main() {
A* a = new C();
if (B* b = dynamic_cast<B*>(a)) {
b->fooB();
} else if (C* c = dynamic_cast<C*>(a)) {
c->fooC();
b->fooB();
}
return 0;
}
It compiles and the output is thus:
fooC
fooB
This is surely wrong. Do I need to enable some warning(s) to prevent this code from compiling?
Imagine the horrors if I tried to access some member variables or call a virtual function!
Same behaviour both in VS2008 an GCC 4.8
It does exist, but b is NULL on the else branch, and calling a function on it is undefined behavior.

Thread in class virtual member function

I want to make a threading object, the member function "run" can be overridden. When I add the word "virtual", it will fail. Can someone help me - how can i make a threading object. The object can be inherited and the member function can be overridden.
#include <iostream>
#include <process.h>
using namespace std;
class thread
{
private:
static void gangplank(void *ptr)
{
((thread *)ptr)->run();
}
public:
void start()
{
_beginthread(&this->gangplank,0,(void *)this);
//this->gangplank((void *)this);
}
virtual void run()
{
cout<<1;
}
~thread()
{
_endthread();
}
};
class d:public thread
{
public:
void run()
{
cout<<2;
}
};
int main()
{
d a;
a.start();
return 0;
}
The error message:
"text.exe Has stopped working - Windows is checking for a solution to the problem"
It didn't have compile error.
I don't know if this is your problem, since you just say that it
failed, without saying how, but you don't wait for the thread to
finish in main, so you may be destructing the thread object
before the thread starts to run.
Remove _endthread from destructor.
MSDN:
You can call _endthread or _endthreadex explicitly to terminate a
thread; however, _endthread or _endthreadex is called automatically
when the thread returns from the routine passed as a parameter to
_beginthread or _beginthreadex. Terminating a thread with a call to endthread or _endthreadex helps to ensure proper recovery of resources
allocated for the thread.
Ok, I got it now, _endthread in destructor it's not real problem here, you must wait for thread in the main function.
#include <process.h>
#include <iostream>
using namespace std;
class thread
{
private:
HANDLE m_handle;
static void gangplank(void *ptr)
{
((thread *)ptr)->run();
}
public:
HANDLE getHandle() const {return m_handle;}
void start()
{
m_handle = (HANDLE)_beginthread(&this->gangplank,0,(void *)this);
}
virtual void run()
{
cout<<1;
}
~thread()
{
//_endthread();
}
};
class d:public thread
{
public:
void run()
{
cout<<2;
}
};
int main()
{
d a;
a.start();
WaitForSingleObject(a.getHandle(), INFINITE);
return 0;
}
Use std::thread instead of the native C API. It uses function objects, so you probably won't even need virtual functions. If your compiler doesn't support C++11, then you can use boost::thread, which is almost the same (actually, it uses the native API directly).
Here is an example:
#include <thread>
#include <iostream>
void run()
{
std::cout << "run" << std::endl;
}
int main()
{
std::thread t(run);
t.join();
}
Or you can also call class members:
#include <thread>
#include <functional>
#include <iostream>
class A {
public:
void run()
{
std::cout << "run" << std::endl;
}
};
int main()
{
A a;
std::thread t(std::bind(&A::run, &a));
t.join();
}
It is generally advised to use higher-level API if possible instead of creating a wrapper to C library calls yourselves. APIs in the C++ standard (and usually in Boost too) are generally better implemented than an average programmer could do, and it surely saves a lot of time than making a good implementation yourself.

C++11: std::thread inside a class executing a function member with thread initialisation in the constructor

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.