Access class variable from std::thread - c++

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

Related

Crash when method of class is executing but smart pointer deleted the object

I faced a problem with C++ memory management and smart pointers.
I have a code to demonstrate you the problem:
#include <memory>
class Closeable
{
public:
virtual void Close() = 0;
};
class DisconnectionHandler
{
public:
virtual void HandleDisconnection() = 0;
};
class EventHandler
{
public:
virtual void HandleEvent() = 0;
};
class Notifier
{
public:
virtual void OnDisconnection() = 0;
};
class RemoteSystem : public Closeable
{
public:
void SetReceiveDataEventHandler(const std::shared_ptr<EventHandler>& receive_data_event_handler) {
this->receive_data_event_handler_ = receive_data_event_handler;
}
void Close() override { this->receive_data_event_handler_ = nullptr; }
// In this example to simplify the code I just call this method from the main function.
void OnDataReceived() { this->receive_data_event_handler_->HandleEvent(); }
private:
std::shared_ptr<EventHandler> receive_data_event_handler_;
};
class ReceiveDataEventHandler : public EventHandler
{
public:
explicit ReceiveDataEventHandler(const std::shared_ptr<DisconnectionHandler>& disconnection_handler)
: disconnection_handler_(disconnection_handler) {}
void HandleEvent() override {
// Some code of receiving data.
// But we can find out that connection was closed and we must call the disconnection handler.
if (this->IsConnectionClosed()) {
this->disconnection_handler_->HandleDisconnection();
return;
}
// Some other stuff..
}
private:
[[nodiscard]] bool IsConnectionClosed() const {
// In the example code I just return true.
return true;
}
private:
const std::shared_ptr<DisconnectionHandler> disconnection_handler_;
};
class RemoteSystemDisconnectionHandler : public DisconnectionHandler
{
public:
explicit RemoteSystemDisconnectionHandler(const std::shared_ptr<Closeable>& closeable_remote_system,
Notifier* notifier)
: closeable_remote_system_(closeable_remote_system), notifier_(notifier) {}
~RemoteSystemDisconnectionHandler() { printf("Destructed.\n"); }
void HandleDisconnection() override {
this->closeable_remote_system_->Close();
printf("Closed.\n");
this->notifier_->OnDisconnection();
printf("Notified.\n");
}
private:
const std::shared_ptr<Closeable> closeable_remote_system_;
Notifier* const notifier_;
};
class ClientNotifier : public Notifier
{
public:
void OnDisconnection() override { printf("Disconnected.\n"); }
};
int main() {
ClientNotifier notifier;
auto remote_system = std::make_shared<RemoteSystem>();
{
// Scope for losing references in the main function after SetReceiveDataEventHandler.
auto disconnection_handler = std::make_shared<RemoteSystemDisconnectionHandler>(remote_system, &notifier);
auto receive_data_event_handler = std::make_shared<ReceiveDataEventHandler>(disconnection_handler);
remote_system->SetReceiveDataEventHandler(receive_data_event_handler);
}
// Only in the example.
remote_system->OnDataReceived();
return 0;
}
You can also run this code. In this example program crashes on the line this->notifier_->OnDisconnection(). The output of the program:
Destructed.
Closed.
*crash*
This occurs because of losing the last reference to the ReceiveDataEventHandler when calling method RemoteSystem::Close from RemoteSystemDisconnectionHandler::HandleDisconnection, accordingly, losing the reference to the RemoteSystemDisconnectionHandler and deleting this object. After the Close method and deleting both objects of classes RemoteSystemDisconnectionHandler and ReceiveDataEventHandler it returns to the RemoteSystemDisconnectionHandler::HandleDisconnection method and prints 'Closed.' to the output, but since the object has been already deleted, the next line occurs an error, because now this is deleted and any access to it occurs memory exception.
I also tried to rewrite this code on Java and it works fine, unlike C++.
So, I want to ask you guys if there is a solution for this problem in the C++ community?
I thought C++ had no problems with memory management since smart pointers exist, but appearently I was wrong.
Hope for your help!
Thanks in advance!
A simple solution is to make a copy of the shared_ptr before invoking the method on it:
void OnDataReceived()
{
auto temp = this->receive_data_event_handler_;
if (temp)
{
temp->HandleEvent();
}
}
temp will keep the pointer alive until after the method invocation has completed.
However note that if you are using multiple threads in your real code, std::shared_ptr is not thread safe so you need to introduce a mutex to protect access to receive_data_event_handler_:
class RemoteSystem : public Closeable
{
public:
void SetReceiveDataEventHandler(const std::shared_ptr<EventHandler>& receive_data_event_handler) {
this->receive_data_event_handler_ = receive_data_event_handler;
}
void Close() override
{
std::unique_lock lock(mutex);
this->receive_data_event_handler_ = nullptr;
}
// In this example to simplify the code I just call this method from the main function.
void OnDataReceived()
{
std::shared_ptr<EventHandler> temp;
{
std::unique_lock lock(mutex);
temp = this->receive_data_event_handler_;
}
if (temp)
{
temp->HandleEvent();
}
}
private:
std::shared_ptr<EventHandler> receive_data_event_handler_;
std::mutex mutex;
};

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 )

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

Passing a function pointer to a function

What should I do if I want to pass a non-static member function of any class as a click function of the button ? Is it possible ? If so what do I need to do ? For example in which ever class (EntityToolGUI over here) the button is initiatlized, I want to set its click action to a non-static member function (a non-static member function of class EntityToolGUI ) of that class.
GUIButton.h
typedef void (*ptr2clickFunc)(void);
class GUIButton : public GUIObject {
private : void (*clickFunc)(void);
public : void setClickFunction(ptr2clickFunc clickFunc);
};
GUIButton.cpp
void GUIButton::setClickFunction(ptr2clickFunc clickFunc)
{
this->clickFunc = clickFunc;
}
EntityToolGUI.h
class EntityToolGUI {
public : EntityToolGUI();
protected : void addAnimation();
}
EntityToolGUI.cpp
void EntityToolGUI::addAnimation()
{
cout<<"add animation"<<endl;
}
EntityToolGUI::EntityToolGUI()
{
....
btnAddAnimation->setClickFunction(&EntityToolGUI::addAnimation);
}
I am getting an error no matching function call to GUIButton::setClickFunction(void (EntityToolGUI::*)())
candidate is void GUIButton::setClickFunction(void (*)())
How do I solve this ?
Most (decent) C code that passes function pointers around use an extra void* argument for passing user context to the function. This is not so common in C++ (as better techniques than function pointers exist), but if you're stuck using function pointers for some reason then it may be appropriate.
typedef void (*ptr2clickFunc)(void*);
class GUIButton : public GUIObject {
private : ptr2clickFunc clickFunc;
private : void * userdata;
public : void setClickFunction(ptr2clickFunc clickFunc, void* userdata);
};
class Foo
{
static void do_foo( void * userdata )
{
Foo* thisptr = static_cast<Foo*>(userdata);
thisptr->foo();
}
void foo() { ... }
};
int main()
{
Foo foo;
GUIButton button;
button.setClickFunction( &Foo::do_foo, &foo );
button.click();
}
EDIT As noted by Bartek, if you're doing this a lot you can extract the static function into a template - it looks a bit like this (untested and probably with minor errrors).
// GUIButton is as before
// Note no static function here
class Foo { void foo(); }
template<typename T, void(T::*FN)() >
void Call( void * data)
{
static_cast<T*>(data)->*FN();
}
int main()
{
Foo f;
GUIButton button;
button.setClickFunction( &Call<Foo,&Foo::foo>, &f );
button.click();
}
If you want to pass obj fun ptr you can use boost::bind and boost::function
http://www.boost.org/doc/libs/1_50_0/libs/bind/bind.html
You cannot pass a pointer to non-static member function as a pointer to a "regular" non-member function. You should either make addAnimation static, or make ptr2clickFunc typedef a pointer to member function.
Note that invoking a pointer to member function is different from invoking a function pointer, because you must supply an instance on which the member pointer is to be invoked.
addAnimation needs to be static function. When the call back function is set the way you are doing it now, the object of class EntityTollGUI is not registered along with the function.
Try this one (C++11):
#include <stdio.h>
#include <stdlib.h>
#include <functional>
class Raiser
{
public:
std::function<void(int)> ev1, ev2;
void RaiseEv1()
{
if (!ev1._Empty())
ev1(44);
}
void RaiseEv2()
{
if (!ev2._Empty())
ev2(66);
}
};
class Handler
{
private:
int id;
std::function<void(int)> h;
public:
Handler(int newId)
{
id = newId;
h = [this](int i)
{
printf("Handler with id = %d captured event!\n", this->GetId());
};
}
void Hook1(Raiser & raiser)
{
raiser.ev1 = h;
}
void Hook2(Raiser & raiser)
{
raiser.ev2 = h;
}
int GetId()
{
return id;
}
};
int main(int argc, char * argv[])
{
Raiser raiser;
Handler handler1(1), handler2(2);
handler1.Hook1(raiser);
handler2.Hook2(raiser);
raiser.RaiseEv1();
raiser.RaiseEv2();
getchar();
}
AFAIK, this is the most you can get with events in C++ without using language extensions.

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.