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.
Related
This question already has answers here:
Passing arguments to std::async by reference fails
(3 answers)
Closed 3 years ago.
I'm trying to use std::async inside a member function in the following way:
#include <iostream>
#include <vector>
#include <string>
#include <future>
using namespace std;
class splitter
{
public:
splitter() = default;
virtual ~splitter() = default;
bool execute(vector<string> &vstr);
bool split_files(vector<string> &vstr);
};
bool splitter::split_files(vector<string> &vstr)
{
for(auto & file : vstr)
{
// do something
cout << file << endl;
}
return true;
}
bool splitter::execute(vector<string> &vstr)
{
auto fut = std::async(std::launch::async, split_files, vstr);
bool good = fut.get();
return good;
}
int main()
{
vector<string> filenames {
"file1.txt",
"file2.txt",
"file3.txt"
};
splitter split;
split.execute(filenames);
return 0;
}
I would like to use std::async inside a member function to execute another member function in a separate thread, which takes a vector of strings as a parameter.
compiling with gcc (9.1) I get the following error:
..\cpp\tests\threads\async1\main.cpp|29|error: no matching function
for call to
'async(std::launch, <unresolved overloaded function type>,
std::vector<std::__cxx11::basic_string<char> >&)'|
Use std::ref to pass vstr by reference.
Because split_files is member function you need to pass this on which this function will be called.
auto fut = std::async(std::launch::async, &splitter::split_files, this, std::ref(vstr));
Live demo
I hope you are aware that execute function is blocking, you don't have any profit by starting async task inside it.
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()
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;
}
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));
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();
});