Thread in class virtual member function - c++

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.

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;
}

Is it safe to create a global object that has an independent thread?

Take a look at the following sample,
#include <iostream>
#include <thread>
class GPS
{
public:
GPS() { this->init(); }
~GPS() {m_thread.join();}
private:
std::thread m_thread;
void init() { m_thread = std::thread(&GPS::update,this); }
void update() { /*get data from gps sensor.*/ };
};
GPS myGPS;
int main()
{
return 0;
}
What is/are the consequences of creating an object globally that has its own thread? Is this safe approach? if No, what are the alternatives with the assumption that the object must be global and has an independent thread? Thank you.
if No, what are the alternatives.
Lazy evalutation: Don't create the thread until the first time it actually is needed.

using callbacks with threads

Modified to explain better the problem:
I wish to pass a callback function from one class to another , from class1 to class2. I don't want class2 to know anything about class1.
My below code works fine, but I would like to involve using different threads here. The code has been simplified very much by excluding the separate cpp files for the classes etc. but hopefully I get my idea across.
I would like class1 to be running some thread calling different member functions of class1 and then have class2 calling its member functions, hence the function that handles the callback from class1.
I'm not sure how to implement this. If there is a thread already running in class2 that is calling "FuncToExecuteCallback". How can I register the callback from the different thread running in class1. Or should I just start a thread running inside "FuncToExecuteCallback" when it is called.
Any help is much appreciated . Thanks
// class which contains callback to be sent to another class
class class1
{
public:
class1(class2& d);
// call back function to be passed elsewhere
void MyCallBack()
{
cout<<"Inside CallBack Function!!"<<endl;
}
void RegisterCallback()
{
d.FuncToExecuteCallback(std::bind(&class1::MyCallBack, this));
}
void CheckValues()
{
//some code
}
private:
class2& d;
};
// class which handles the callback
class class2
{
public:
bool mySignal = false;
typedef std::function<void(void)> funcType;
void FuncToExecuteCallback( funcType f)
{
//This function should be running in a separate thread
for (;;)
{
if (mySignal == true)
f();
}
};
// main function
int main(int argc, char *argv[])
{
class2 c2;
std::thread th1
{
[&]{
class1 c1{c2};
c1.RegisterCallback(); // I'd like a separate thread to be spawn here that would call FuncToExecuteCallback from class2
for (;;)
{
c1.CheckValues();
// execute more functions from class1 ....
// ...
}
};
}
Just add a mutex to your code:
#include <mutex>
class class2;
class class1{
public:
class1(class2 &c2): m_c2{c2}{}
void func(){}
void RegisterCallback();
private:
class2 &m_c2;
};
class class2{
public:
template<typename Func>
void ExecuteFunc(Func &&f){
std::unique_lock<std::mutex> lock{m_mut};
f();
}
private:
std::mutex m_mut;
};
void class1::RegisterCallback(){
m_c2.ExecuteFunc([this]{ this->func(); });
}
Then no matter how many class1's call ExecuteFunc on the same class2 there will be no race on any data within the class2. This gives no guarantee about order of locking, though.
e.g. to run ExecuteFunc in multiple threads from main:
#include <thread>
#include "myclasses.hpp"
int main(int argc, char *argv[]){
myclass2 c2;
std::thread th0{
[&]{
class1 c1{c2};
c1.RegisterCallback();
}
};
std::thread th1{
[&]{
class1 c1{c2};
c1.RegisterCallback();
}
};
th0.join();
th1.join();
}

Using C++11 thread with pure virtual thread function

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.

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.