using callbacks with threads - c++

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

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

understanding std::thread semantic with worker function as class member

To implement the logic when contructed object starts background thread for real work, I'm using a pattern like this (simplified):
class A {
std::thread t{&A::run, this};
std::atomic_bool done;
// variables are the question about
std::vector<std::thread> array_for_thread_management;
// ... and other members
protected:
void run() {
...
array_for_thread_management.push_back([](){...});
...
}
public:
A() = default;
// all other constructors deleted because of used
// some members like std::atomic_bool done;
~A() {
done = true;
bi::named_condition cnd{bi::open_only, "cnd"};
cnd.notify_one();
if (t.joinable())
t.join();
for(std::thread& worker : array_for_thread_management) {
if (worker.joinable()) worker.join();
}
}
};
If I'm adding a push of child threads in primary background thread into a vector in run() member, the object hangs on destructor.
even there is no real threads in a vector, just started this without connections from outside and try to stop this by destructor
Of course, once you have this pointer in your run method, you can access class members via this pointer. I guess the problem with your code is that the thread is spawned before any other members are initialized, as it is the first member in your class definition. I suspect with the following definition of class A you'll have no problems with accessing member variables:
class A {
std::atomic_bool done;
// variables are the question about
int i;
std::string s;
std::vector<std::string> v;
// and only after everything above is initialized:
std::thread t{&A::run, this}; // spawn a thread
// ...
}
However, personally I would prefer having a separate method start() which spawns a thread to spawning it inside class constructor implicitly. It may look like this:
class A
{
std::unique_ptr<std::thread> t;
std::atomic<bool> some_flag;
public:
void start()
{
t.reset(new std::thread(&A::run, this));
}
private:
void run()
{
some_flag.store(true);
}
};

c++ , pthread and static callbacks. "this" returns a pointer to the base class inctead of the derived one [duplicate]

This question already has an answer here:
c++ , pthread and static callbacks. "this" returns a pointer to the base class inctead of the derived one (part 2)
(1 answer)
Closed 7 years ago.
I am using as basis this cpp thread class. This I use as a base class for threads. Note that in my case Thread::main() is a virtual function (unlike in the link). So I basically use:
class Thread {
public:
virtual void main()
{
cout << "This should not be run once derived and redefined." << endl;
}
void run()
{
pthread_create(&thread, 0, &callback, this);
}
pthread_t thread;
}; // class Thread
void* callback(void* obj)
{
static_cast<Thread*>(obj)->main();
return(0);
} // callback
Then I create a derived class and re-define the myThreadedClass::main() member to actually do something meaningful.
Finally, I instantiate the myThreadedClass object from other classes or my main function call as follows:
main(int argc, char** argv){
myThreadedClass thr;
thr.run();
//do other stuff
}
This works fine; The callback function gets a pointer to the derived class instantiation, so the myThreadedClass::main() gets executed.
However, I now try to create a different derived class class otherThreadClass : public Thread. Again I re-define my otherThreadClass::main() , but now I have a member function in the derived class which (unlike before) calls Thread::run().
class otherThreadClass : public Thread{
public:
writeToDiskAsync(string& str){
prepareString(str);
//spawn a thread to carry the write without blocking execution
run();
}
};
in this case from my main function I do
main(int argc, char** argv){
otherThreadClass thr;
thr.writeToDiskAsync(aString);
//do other stuff
}
The problem in this case is that the callback function gets a pointer to the Thread class and the Thread::main() ends up being executed instead of the otherThreadClass::main().
I tried passing a pointer to the instantiated myThreadedClass object during instantiation (using initialisation lists and an altered call to Thread::run(void* instance)) as follows
//in main function
otherThreadClass thr(&thr);
//in class
otherThreadClass::otherThreadClass(otherThreadClass* ptr):instancePtr(ptr)
{}
otherThreadClass::writeToDiskAsync(string& str)
{
//do stuff
run(instancePtr);
}
//and finally
Thread::run(void* parentObj)
{
pthread_create(&thread, 0, &callback, parentObj);
}
but it does not work. And I think this is probably not a nice way to do it anyway. So what can I do to let the callback function get apointer to the derived class instance instead of the base class ?
thank you
If you will try to call a function using base class ptr , everytime base class version gets called as long as function is not virtual .
so simpler solution to your problem would be to make main virtual as below :
#include <iostream>
#include<pthread.h>
#include<unistd.h?
using namespace std;
void* callback(void* obj);
class Thread {
public:
virtual int main()
{
cout << "Hi there Base class" << endl;
return(0);
}
void run()
{
pthread_create(&thread, 0, &callback, this);
}
pthread_t thread;
};
class otherThreadClass : public Thread{
public:
virtual int main()
{
cout << "Hi there other class" << endl;
return(0);
}
void writeToDiskAsync(string str){
//spawn a thread to carry the write without blocking execution
run();
}
};
class Thread;
void* callback(void* obj)
{
static_cast<Thread*>(obj)->main();
return(0);
} // callback
int main() {
// your code goes here
otherThreadClass thr;
thr.writeToDiskAsync(string("aS"));
sleep(10);//it is neccessary as main thread can exit before .
return 0;
}
output : Hi there other class
Whereas if main is not virtual , it will always call base class version of main as you are calling through a base class ptr (static binding will happen )

Access class variable from std::thread

I have the following class which kicks off a new std::thread. I now want the thread to access a member variable of the class. So far I cannot work out how to do this.
In my MyThread function I want to check m_Continue.
I have tried passing in 'this' when the thread is created but I get an error:
Error 1 error C2197: 'void (__cdecl *)(void)' : too many arguments for call c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional 1152 1 MyProject.
class SingletonClass
{
public:
SingletonClass();
virtual ~SingletonClass(){};
static SingletonClass& Instance();
void DoSomething();
private:
static void MyThread();
std::thread* m_Thread;
bool m_Continue;
};
SingletonClass::SingletonClass()
{
m_Continue = true;
m_Thread= new std::thread(MyThread, this);
}
void SingletonClass::MyThread()
{
while(this->m_Continue )
{
// do something
}
}
void SingletonClass::DoSomething()
{
m_Continue = false;
}
SingletonClass& SingletonClass::Instance()
{
static SingletonClass _instance;
return _instance;
}
int _tmain(int argc, _TCHAR* argv[])
{
SingletonClass& singleton = SingletonClass::Instance();
singleton.DoSomething();
return 0;
}
How can I do this??
If you want to access this from within the thread function, then it shouldn't be static:
void MyThread();
Now you can simply pass this as the second thread constructor argument, as you tried; but, being a non-static member, you'll need to qualify its name:
m_Thread= new std::thread(&SingletonClass::MyThread, this);
Alternatively, you might find a lambda easier to read:
m_Thread= new std::thread([this]{MyThread();});
But you shouldn't muck around with pointers and new like that; make the member variable a thread object and initialise it in the initialiser list:
SingletonClass::SingletonClass() :
m_Continue(true), m_Thread([this]{MyThread();})
{}
making sure to declare m_Thread after any other members that it accesses; and make sure you stop and join the thread in the destructor, or earlier.
Finally, m_Continue should be std::atomic<bool> in order to set it on one thread and read it on another with well-defined behaviour.
Replace
static void MyThread();
with
void MyThread();
as
this cannot be access within static method.
You can access the member variable if it is public or you may make have a method like "bool shallContinue()" which returns m_Continue.
Now how do you do this. Check the below modified snippet:
static void SingletonClass::MyThread(SingleTonClass *arg)
{
while(arg->shallContinue() )
{
// do something
}
}
Below a complete example:
#include <iostream>
#include <thread>
#include <unistd.h>
using namespace std;
class A
{
public:
A(int x) : a(x)
{
thr = new thread(myThread, this);
}
static void myThread(A *arg)
{
arg->show();
}
void show()
{
cout << a << endl;
}
private:
int a;
thread *thr;
};
int main()
{
A a(1);
sleep(2);
return 0;
}

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.