Run Member Function in Separate thread - c++

I am trying to run a member function in its own thread and have followed this post, however in that example, the thread starts and finishes in the same function. How do you maintain a reference to the thread to join in a separate member function (say the destructor)? I have tried this:
class foo
{
foo();
~foo();
volatile sig_atomic_t m_run_thread = true;
std::thread &m_read_thread;
void read_thread();
}
foo::foo():m_read_thread(std::thread(&foo::read_thread, this))
{
}
foo::~foo()
{
m_run_thread = false;
m_read_thread.join();
}
void foo::read_thread()
{
while(m_run_thread)
{
//do something cool
}
}
int main()
{
foo bar;
//do other stuff
}
The compiler gives me an error though: error: invalid initialization of non-const reference of type ‘std::thread&’ from an rvalue of type ‘std::thread’. This is caused because I'm trying to bind a temporary to a reference. What's this best way to fix this?

foo::foo():m_read_thread(std::thread(&foo::read_thread, this)) is not going to work as std::thread(&foo::read_thread, this) is a temporary value and a temporary cannot be bound to a non const lvalue reference.
That said there is no reason to make the thread member a reference. You can simple have a std::thread member like std::thread m_read_thread; and then in the constructor you would initialize it like
foo::foo() : m_read_thread(std::thread(&foo::read_thread, this))

Related

How to pass the target function of std::thread constructor as an argument

I can do this to start my thread:
int main_test() {
// do something...
return 0;
}
std::thread* myThread;
void myFunction() {
myThread = new std::thread(main_test);
}
How do I pass main_test as an argument to myFunction, so the same function can be used to start the thread using different target functions? What would the signature of myFunction be then?
I guess what I don't understand is how the templated version of the std::thread constructor is invoked with a specified type.
std::thread myThread;
The type of myThread is std::thread.
myThread = new std::thread(main_test);
new std::thread(main_test) returns std::thread*. You cannot assign std::thread* into a std::thread. The program is ill-formed.
Solution: There appears to be no reason to use dynamic allocation. Simply assign a temporary object like this:
myThread = std::thread(main_test);
How do I pass main_test as an argument to myFunction, so the same function can be used to start the thread using different target functions? What would the identity of myFunction be then?
You can make your myFunction a template with exactly the same arguments as std::thread has, and forward everything. Or, if you want to keep it simple, you can use a function pointer.
How do I pass main_test as an argument to myFunction, so the same function can be used to start the thread using different target functions?
You can pass the poiter to your function as an argument
void myFunction(int (*func)()) {
myThread = new std::thread(func);
}
int callSelector(int someCriteria)
{
if (someCriteria == 0) {
myFunction(main_test1);
}
else {
myFunction(main_test2);
}
}

Passing object to a function in lambda std::thread (C++): attempt to use a deleted function

I'm trying to do something like this:
class A {
private:
std::mutex my_mutex;
public:
void A_function(){
some work with the mutex;
}
};
void B_function (A a){
a.A_function();
}
int main () {
A a;
std::thread t([&a]{
B_function(a); // error here
});
t.join();
}
However, I get this error:
error: attempt to use a deleted function « A »
error: attempt to use a deleted function « std::mutex::mutex(const std::mutex&) »
What am I doing wrong?
std::mutex is not copyable, therefore, you naturally cannot copy an object of type A, which has a subobject of type std::mutex.
As a workaround, you can pass an argument to B_function by reference instead of by copy:
void B_function (A& a)
{
a.A_function();
}
Don't know though whether it suits your needs to work with the original object instead of with its copy.

Access a Variable of an Object from Threads

I need help with my c++ programm.
I start to Threads beside the main function:
thread Thread1(&Foo::Loop1, info,std::ref(info));
thread Thread2(&Foo::Loop2, info,std::ref(info));
info is an object from the class Foo which contains bool active
later I change the active to true but the value in Loop1 or Loop2 dont change. They are everytime the same.
my prototype function looks like this:
void Loop1(Foo info);
void Loop2(Foo info);
the called function:
void Foo::Loop1(Foo info){
while (true){
if (info.active){
//Stuff
}
}
}
So what should I do to pass the value from the object Foo which change in the main function so the value active in the Loop functions are equal.
Thank you for helping :)
If the functions are static members, they should have a reference parameter, Foo&.
void Loop1(Foo& info);
void Loop2(Foo& info);
otherwise the threads get copies of the object you passed.
If they are non-static members you don't need to pass the instance at all:
void Foo::Loop1(){
while (true){
if (active){
//Stuff
}
}
}
thread Thread1(&Foo::Loop1, info);
thread Thread2(&Foo::Loop2, info);
std::ref returns an std::reference_wrapper<T> which is implicitly convertable to T& via its conversion operator. When you pass an std::reference_wrapper<T> to a function which accepts a T by value, the conversion operator is invoked, and the function's local copy of T is constructed via its copy constructor.
#include <functional>
class Object
{
// ...
};
void Func(Object obj)
{
// Some code which modifies obj
}
int main()
{
Object obj;
Func(std::ref(obj)); // <-- Conversion operator invoked, obj passed by value
}
Change the functions to accept Foo by reference.

How to return member that can be changed?

Multi thread enviroment . The content of Foo can be multi thread.
class Foo
{
public:
const A & getA() {return a_;} //has guard
void setA(A newA){a_ = newA;} //has guard
private:
A a_;
};
caller:
A a = foo.getA();
in another question that i asked someone told me that
If you return const& it's guaranteed that life time of variable will be prolonged to lifetime of the reference
, so according to this i dont need to copy the value and i safe even if call to setA on foo done right after i call to getA, but a lot of argument against it was araised , so i feel that this is not correct.
I want to be on the safe side so i change the signature to be :
A & getA() {return a_;}
but the compiler still give me warning that i have reference to local variable. i dont understand why, because as far as i understand (new to cpp) the return value is a copy of foo.a, so what the problem with this?
i am not worried about change of a_ content.(_a.age =4) . i worry about call to set and that my 'a' in the caller will be illegal
You need to be more careful who you listen to. The only time the lifetime of something gets extended if a temporary object is bound immediately to a const-reference. For example, like so:
Foo bar() { return Foo(); }
int main()
{
Foo const & f = bar();
/* stuff */
} // the object referred to by f is extended till here
Your situation is nothing like that. In particular, returning a const-reference does not create a temporary object, so there's nothing here who's life gets prolonged. In particular, the following is definitely an error:
A const & bar() { Foo x; return x.getA(); }
int main()
{
A const & a = bar(); // dangling reference; object dies upon return from Foo::getA()
}

c++ std::bind keeping object alive

Here is the code, it's pretty straightforward.
class Foo
{
public:
void print()
{
std::cout<<"Foo::print\n";
}
};
Game::Game()
{
{
Foo foo;
player.onclick = bind(&Foo::print,foo);
}
player.onclick();
}
After the inner scope is done the foo object goes out of scope, but the print method is still called, I guess this happens because player holds a reference to the foo object? Is there a way to stop this from happening? I don't want objects to stay alive and receive events when they are supposed to be destroyed.
Thanks.
You are binding to a copy of foo; that copy lasts as long as the bound function object, while the original foo is destroyed at the end of its scope.
If you don't want to keep it alive, then bind to a pointer (&foo) or a reference (std::ref(foo)); and then you must be careful not to call the function object once foo has gone out of scope. Note that there's no way to tell from the function object that this has happened; calling it will give undefined behaviour.
In order to safely disconnect the object when it's destroyed, you would have to either arrange for its destructor to reassign onclick, or make some other object responsible for first reassigning onclick, and then destroying the object.
From your description it sounds like you actually want an event loop. While std::bind is useful for something like that it isn't one all by itself. I suggest you have a look at boost.signals
I think you should use shared_ptr when you assign Foo to Player, and keep a weak_ptr to Foo in Player. Then try to lock the weak_ptr in the onclick function to see if Foo is still alive. Something like this:
using namespace std;
class Foo
{
public:
void print()
{
cout<<"Foo::print\n";
}
};
class Player
{
public:
weak_ptr<function<void()>> _onClickFuntion;
void onclick()
{
shared_ptr<function<void()>> tempFunction(_onClickFunction.lock());
if (tempFunction)
tempFunction();
}
}
Game::Game()
{
{
Foo foo;
player._onClickFuntion = shared_ptr<function<void()>>(new bind(&Foo::print,foo));
}
player.onclick();
}