Cpp: How to create a thread with method that requires pointer? [duplicate] - c++

This question already has answers here:
std::thread pass by reference calls copy constructor
(2 answers)
Closed 4 years ago.
I want to create a thread that will automatically join after the work is done. So, I wrote the fallowing code:
#include <iostream>
#include <thread>
#include <chrono>
#include <future>
using namespace std;
class Foo
{
public:
void work(atomic_bool & isWorking);
};
void Foo::work(atomic_bool & isWorking)
{
//dosomestuff;
int myVar = 0;
while (myVar != 5)
{
myVar++;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
isWorking = true;
return;
}
int main()
{
std::atomic<bool> imdone;
imdone = false;
std::thread t1(&Foo::work, Foo(), imdone);
while (true)
{
std::cout << "Is Joinable: " << t1.joinable() << "\n";
if (imdone)
{
imdone = false;
t1.join();
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
cin.get();
}
I thought that I can pass argument like this: std::thread t1(&Foo::work, Foo(), imdone);, but not in case when the argument is a pointer. How am I supose to pass a pointer in this situation?

You create an object of the type whose member you want to call and pass its address like this:
Foo foo; // create an object
std::thread t1(&Foo::work, &foo, ...); // pass its address
In addition you are passing a reference so you need to use std::ref like this:
Foo foo; // create an object
std::thread t1(&Foo::work, &foo, std::ref(imdone)); // use std::ref()

Related

Is it safe to pass a lambda function that goes out of scope to a std::thread

Considering the following code:
#include <iostream>
#include <thread>
#include <chrono>
int main()
{
std::thread t;
{
auto my_lambda = []{
int idx = 0;
while (true) {
std::this_thread::sleep_for (std::chrono::seconds(1));
std::cout << idx ++ << std::endl;
}
};
t = std::thread(my_lambda);
}
t.join();
return 0;
}
Is it safe that the thread runs a lambda function that goes out of scope?
I saw that the constructor of std::thread takes an universal reference for the input function Function&& f and that lambdas are translated into structs. So if the instance of the struct is instantiated inside the scope, the thread will be running the operator() of a dangling reference.
{
struct lambda_translated { void operator()(){ ... } };
lambda_translated instance;
t = std::thread(instance);
}
However I'm not sure that my reasoning is correct.
Side question: does the behavior change if I declare the lambda as an R-value inside the std::thread constructor:
#include <iostream>
#include <thread>
#include <chrono>
int main()
{
std::thread t;
{
t = std::thread([]{
int idx = 0;
while (true) {
std::this_thread::sleep_for (std::chrono::seconds(1));
std::cout << idx ++ << std::endl;
}
});
}
t.join();
return 0;
}
As a summary of the comments:
The lambda is copied (or moved if declared in-place), so you won't have problems.
You have to worry about the captures: do not capture by reference objects that can go out of the scope, or if you pass objects that can be deleted during thread execution (even if copied, think about a raw pointer to an object).
As an extension, same applies if you use std::bind to pass a method and the object goes out of scope or it is deleted.

C++11 multithreading with class member function [duplicate]

This question already has answers here:
Start thread with member function
(5 answers)
Closed 7 years ago.
I want to use multithreading in C++11 to call a class member function in its own thread. I have been able to get this to work with a global function:
#include <thread>
#include <iostream>
void Alpha(int x)
{
while (true)
{
std::cout << x << std::endl;
}
}
int main()
{
std::thread alpha_thread(Alpha, 5);
alpha_thread.join();
return 0;
}
However, I cannot get it to compile with a class member function:
#include <thread>
#include <iostream>
class Beta
{
public:
void Gamma(int y)
{
while (true)
{
std::cout << y << std::endl;
}
}
};
int main()
{
Beta my_beta;
std::thread gamma_thread(my_beta.Gamma, 5);
gamma_thread.join();
return 0;
}
The compile error is:
no matching function for call to 'std::thread::thread(<unresolved overloaded function type>)'
std::thread gamma_thread(my_beta.Gamma, 5);
^
What am I doing wrong?
You need to pass two things: a pointer-to-member, and the object. You cannot call a non-static member function (like Gamma) in C++ without an object. The correct syntax would be:
std::thread gamma_thread(&Beta::Gamma, // the pointer-to-member
my_beta, // the object, could also be a pointer
5); // the argument
You can think of my_beta here as being the first argument to Gamma(), and 5 as the second.
You need to name the function, then pass the object on which to call it as an explicit implicit this parameter. :)
std::thread gamma_thread(&Beta::Gamma, my_beta, 5);
This is a bit of an abstraction leak, granted.
You have multiple problems in your program
As your compile error says, you need to pass the address of the function &Beta::Gamma.
You need to pass the object as a parameter considering this is an implicit parameter of a member function
Modified source
#include <thread>
#include <iostream>
class Beta
{
public:
void Gamma(int y)
{
while (true)
{
std::cout << y << std::endl;
}
}
};
int main()
{
Beta my_beta;
std::thread gamma_thread(&Beta::Gamma, my_beta, 5);
gamma_thread.join();
return 0;
}

C++ std::thread and method class [duplicate]

This question already has answers here:
Start thread with member function
(5 answers)
Closed 8 years ago.
i'm trying to use a function of a class with std::thread
The follow code snippet return an error
MyClass *MyClass_ptr = new MyClass;
MyClass_ptr->MyFunction(); // Works
std::thread ThreadA(MyClass_ptr->MyFunction() ); // Error here
std::thread ThreadB(MyClass_ptr->MyOtherFunction() ); // Error here
I need to make a thread with that specific pointer to the class: MyClass_ptr
So, is there a way to use a method of that class using this specific pointer ?
If it's useful here is the full code compiled with Microsoft Visual Studio 2013
#include "stdafx.h"
#include <iostream>
#include <thread>
class MyClass
{
public:
void MyFunction();
void MyOtherFunction();
};
void MyClass::MyOtherFunction()
{
std::cout << "Inside MyOtherFunction" << std::endl;
std::cin.get();
}
void MyClass::MyFunction ()
{
std::cout << "Inside MyFunction" << std::endl;
std::cin.get();
}
int _tmain(int argc, _TCHAR* argv[])
{
MyClass *MyClass_ptr = new MyClass;
MyClass_ptr->MyFunction(); // Works
std::thread ThreadA(MyClass_ptr->MyFunction() ); // Error here
std::thread ThreadB(MyClass_ptr->MyOtherFunction() ); // Error here
delete MyClass_ptr;
MyClass_ptr = nullptr;
return 0;
}
You need to pass an object on which the member function will be called (remember, every non-static member function has an implicit this parameter) :
#include <thread>
class MyClass
{
public:
void MyFunction();
void MyOtherFunction();
};
int main()
{
MyClass *MyClass_ptr = new MyClass;
std::thread ThreadA(&MyClass::MyFunction, MyClass_ptr);
std::thread ThreadB(&MyClass::MyOtherFunction, MyClass_ptr );
}
You could use a closure.
std::thread ThreadA( [MyClass_ptr](){
MyClass_ptr->MyFunction();
});
Yes you will need to use bind. The following example is for boost bind but you could always use the C++11 version of bind.You could use it like this
boost::thread t(boost::bind(&sommeclass::someMethod, ptr_instance_of_someclass,parameters_if_any));
so in your case it will be
boost::thread ThreadA(boost::bind(MyClass::MyFunction,MyClass_ptr));

Calling an objects member function in a thread in main() [duplicate]

This question already has answers here:
Start thread with member function
(5 answers)
Closed 9 years ago.
I have found a lot about creating a new thread within a class (Passing member functions to std::thread)
But is it somehow possible to do the following:
#include <iostream>
#include <thread>
using namespace std;
class myClass
{
public:
myClass(){
myInt = 2;
};
void myFun(){
++myInt;
}
int ret_myInt(){
return myInt;
}
private:
int myInt;
};
int main ( void )
{
myClass myObj_;
std::thread t1( myObj_.myFun ); // (1)
t1.join();
cout << myObj_.ret_myInt() << endl;
return 0;
}
The Code is not working, because i cannot call a member function here (1). Is there a simple way to do that?
To be clear: I don't want to create the thread inside the member function.
You can use std::bind:
std::thread t1(std::bind(&myClass::myFun, std::ref(myObj_)));
Or you can use a lambda, or the variadics interface to the thread constructor.
std::thread t3([&myObj_]() { myObj_.myFun(); }); // lambda
std::thread t2(&myClass::myFun, std::ref(myObj_)); // variadics
It all comes down to the same.
You need to pass a function pointer and the object instance as separate arguments to the thread constructor:
std::thread t1(&myClass::myFun, &myObj);
This will cause the myFun member function being called, with its first argument being a pointer to the myObj instance, just like member functions wants it.

std::thread notation when defining the threaded function

I understand the std::thread notation presented here and reproduced as follows
#include <iostream>
#include <utility>
#include <thread>
#include <chrono>
#include <functional>
#include <atomic>
void f1(int n)
{
for (int i = 0; i < 5; ++i) {
std::cout << "Thread " << n << " executing\n";
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
void f2(int& n)
{
for (int i = 0; i < 5; ++i) {
std::cout << "Thread 2 executing\n";
++n;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
int main()
{
int n = 0;
std::thread t1; // t1 is not a thread
std::thread t2(f1, n + 1); // pass by value
std::thread t3(f2, std::ref(n)); // pass by reference
std::thread t4(std::move(t3)); // t4 is now running f2(). t3 is no longer a thread
t2.join();
t4.join();
std::cout << "Final value of n is " << n << '\n';
}
because the definition of f1 and f2 is within main but fail to understand
#ifndef THREADED_H_
#define THREADED_H_
class Threadme
{
long count;
public:
Threadme();
void run(void);
void delay(long);
};
#endif
#include "threaded.h"
#include <iostream>
#include <chrono>
Threadme::Threadme() : count(0) {}
void Threadme::delay(long seconds)
{
std::chrono::steady_clock::time_point end_t = std::chrono::system_clock::now() + std::chrono::seconds(seconds);
while(std::chrono::system_clock::now() < end_t)
;
}
void Threadme::run(void)
{
while(count < 10)
{
++count;
std::cout << count << std::endl;
delay(1);
}
}
#include <cstdlib>
#include <thread>
#include "threaded.h"
int main(int argc, char *argv[]){
std::thread t1(&Threadme::run, Threadme());
t1.join();
return EXIT_SUCCESS;
}
specifically the expression std::thread t1(&Threadme::run, Threadme()); as it relates to defining the threaded function run outside of main. Why the reference & and why the thread parameters is a constructor invocation?
&Foo::mem where Foo is a class type and mem a member (function or value) of Foo, is C++ notation for obtaining a pointer to a member (function or value). There exist a special syntax for invoking a member function pointer on an object, but this is usually sugared away by using std::mem_fun, which will turn a member function pointer into an ordinary function where the first argument has to be an object of the type the member function was taken from.
std::thread understands what is happening here and does exactly that: invoke Foo::mem on the object passed as the second argument.
A small example to reproduce this locally without actually involving std::thread:
#include <functional>
class Foo { void mem() {} };
int main() {
Foo f;
f.mem(); // normal invoke
auto func = std::mem_fun(&Foo::mem);
func(std::ref(f)); // invoke mem on f
func(f); // invoke mem on a copy of f
func(&f); // invoke mem on f through a pointer
}
Why don't we need the mem_fun when constructing std::thread? It
automatically detects those situations through an overload and does
the right thing all by itself.
You can see a member function of ThreadMe as a function that accepts an implicit first parameter of type ThreadMe* - also known as this. This analogy is not 100% correct and might be shred to pieces by some language lawyer, but it serves for understanding the call you have there.
std::thread and many other classes/functions that accept functions and parameters for them, like e.g. std::bind and std::function accept pointers to member functions, followed by an object on which the function has to be called, or put otherwise, followed by that implicit first parameter.
So void ThreadMe::run() can be seen as void run(ThreadMe&); Then the call that bothers you is easy to understand. Consider your second example:
void f1(int n);
int n;
std::thread t2(f, n); //calls f in a new thread, passing n
now create the int just when it's needed:
std::thread t2(f, int()); //calls f, passing a copy of the int that has been created here...
with ints that might not make so much sense, but with an object it does:
void run(ThreadMe&);
std::thread t1(run, ThreadMe()); //conceptually the same as above
and since we know thet member functions are just a bit more than syntactic sugar for that implicit first argument, the call you have is still nothing else but the above:
void ThreadMe::run(); //implicit first argument is a ThreadMe&
std::thread t1(ThreadMe::run, ThreadMe()); //pass a copy of that newly created ThreadMe as the implicit first argument of the run method.
If you know lambdas, this is very similar, i.e. it passes a copy of a fresh ThreadMe to the thread that calls run on that copy::
ThreadMe threadMe;
std::thread t1([=](){ threadMe.run(); });
In fact, since the binding of parameters to functions that happens under the hood of std::thread's constructor is somewhat unusual, I prefer using lambdas, since they explain explicitly anything the thread has to do. In this case I would not create that temporary ThreadMe to call the thread, I would create a nontemporary inside the thread itself:
std::thread t1([](){
ThreadMe threadMe;
threadMe.run();
});