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

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

Related

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

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

C++ Threading with Boost Library

I want my function running in a separate thread. I use Boost library and include like this in my main.cpp:
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
I want the thread start like this:
boost::thread ethread(Engine::function,info);
// info is an object from the class Engine and i need this in the
// function
My Engine class is in the func.h and the function looks like this:
void Engine::function(Engine info)
{
//STUFF
boost::this_thread::sleep(boost::posix_time::milliseconds(1));
}
BTW: Is the sleep function for the thread right?
Every time I want to compile it gives me this error:
error C3867: "Engine::function": function call missing argument list; use '&Engine::function' to create a pointer to member
I tried to use &Engine::function in the thread and this error appears:
error C2064: term does not evaluate to a function taking 2 arguments
I also tried:
boost::thread ethread(Engine::function,info, _1);
Then this error appeared:
error C2784: "result_traits<R,F>::type boost::_bi::list0::operator [](const boost::_bi::bind_t<R,F,L> &) const"
Can someone help me with this? I only want to run the function beside the main thread.
You should use bind function to create functional object with pointer to class member function or make your function static.
http://ru.cppreference.com/w/cpp/utility/functional/bind
More detailed explanation:
boost::thread constructor needs pointer to a function. In case of normal functions syntax is simple: &hello
#include <boost/thread/thread.hpp>
#include <iostream>
void hello()
{
std::cout << "Hello world, I'm a thread!" << std::endl;
}
int main(int argc, char* argv[])
{
boost::thread thrd(&hello);
thrd.join();
return 0;
}
But if you need pointer to a function of class you have to remember that such functions have implicit parameter - this pointer, so you have to pass it also. You can do this by creating callable object with std::bind, or boost bind.
#include <iostream>
#include <boost/thread.hpp>
class Foo{
public:
void print( int a )
{
std::cout << a << std::endl;
}
};
int main(int argc, char *argv[])
{
Foo foo;
boost::thread t( std::bind( &Foo::print, &foo, 5 ) );
t.join();
return 0;
}

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

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.

Can you initialize a thread in a class which references a function inside that class?

I have the following code, which does not compile using
clang++ -std=c++11 -pthread threaded_class.cpp -o test
and
#include <iostream>
#include <thread>
class Threaded_Class {
public:
Threaded_Class();
void init();
};
Threaded_Class::Threaded_Class() {
std::thread t1(init);
t1.join();
}
void Threaded_Class::init() {
std::cout << "Hello, world" << std::endl;
}
int main() {
Threaded_Class a;
return 0;
}
I am given the following compiler errors, which seem a little ambiguous
threaded_class.cpp:13:20: error: reference to non-static member function must be
called; did you mean to call it with no arguments?
std::thread t1(init);
^~~~
()
threaded_class.cpp:13:17: error: no matching constructor for initialization of
'std::thread'
std::thread t1(init);
^ ~~~~~~
Is it legal to initialize a thread this way?
Another method would be to use std::bind
#include <functional>
# instead of std::thread t1(init);
std::thread t1(std::bind(&Threaded_Class::init,this));
This provides the class instance.
because the function is non static the thread has no class instance to call that method on. To do this you can create a static function that will forward your call to your init:
class Threaded_Class {
public:
Threaded_Class();
void init();
static void static_init(Threaded_Class * instance)
{
instance->init();
}
};
Threaded_Class::Threaded_Class() {
std::thread t1(static_init,this);//new line
t1.join();
}