i am using the c++11 thread library with classes, and it works fine.
I just need an explanation for this code so i understand it correctly.
My class.h
class foo {
private:
std::thread t1;
void worker();
public:
void work();
};
the class.cpp
#include "class.h"
void foo::worker() {
std::cout << "worker..." << std::endl;
}
void foo::work() {
t1 = std::thread(&foo::worker, this);
t1.join();
}
and now the main.cpp
#include "class.h"
int main(int argc, char **argv) {
foo bar;
bar.work();
}
What I don't really understand is the invocation of the class-function for the thread.
I use std::thread(&foo::work, this) and interpret this call as follows:
The first parameter is the pointer to the function, but i dont know why i cant just call it
without the &foo:: part.
The second parameter is the class itself that the thread knows the parent process?
I couldn't find a explaination for this. Only the code and i would like to understand it.
Thanks!
&foo::work is required because work is a member function that belongs to class foo. A (non-static) member function can only be accessed if also the object it belongs to is known.
The this parameter is a pointer to the object of which the method should be called.
The address bit is just the syntax for expressing the address of a member function. I believe this could also be expressed as this->worker. I don't know why worker by itself is not allowed---it seems unambiguous, but that's C++.
You have to pass both the member function pointer and this so that the thread can invoke the member function on the correct object. Internally the thread holds a member function pointer, say pmf (pointing to foo::worker), and the object pointer, say po (pointing to the this that was passed). It needs to be able to invoke (po->*pmf)(), which result in worker being invoked on the correct object.
Related
So I have done some research, and have found you can create a boost::thread object and have it start with a non-static class function by using "this" and boost::bind etc. It really doesn't make much sense to me and all the examples I could find had the boost::thread object launched within the same class as the function it was starting with so this could be used. I however, am launching the thread in a different class so I'm afraid by using "this", I will be saying the "this" is from the class I am creating the thread from, rather than the one the function is in (I'm probably wrong, I need to learn more about this "this" guy). Here is an example of my source I am having the problem with.
ANNGUI.h
class ANNGUI
{
private:
boost::thread *GUIThread;
Main *GUIMain;
public:
// Creates the entire GUI and all sub-parts.
int CreateGUI();
}
ANNGUI.cpp
int ANNGUI::CreateGUI()
{
GUIMain = new Main();
GUIThread = new boost::thread(GUIMain->MainThreadFunc);
};
This isn't all the source, but I think my problem is in here somewhere, I know I have to deal with the "this" somehow, but I'm unsure how. I Could use a static function, but I didn't really want to make my variables static either.
Thanks.
Also, Is there any very good resource for using any boost libraries? Their web site documentation seems good, but over my head.
The this keyword is used with boost::bind when the function object you're creating is bound to a object member function. Member functions can't exist apart from instances, so when creating a functor object out of a member function with boost::bind, you need a pointer to an instance. That's exactly what the this keyword actually is. If you use the this keyword within a member function of a class, what you get is a pointer to the current instance of that class.
If you were to call bind from outside a class member function, you might say something like:
int main()
{
Foo f;
boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, &f));
}
Here, we're using Foo::some_function as our thread function. But we can't use this because we're calling bind from main. But the same thing could be achieved using this if we called bind from within a member function of Foo, like so:
void Foo::func1()
{
boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, this));
}
If a member function is static, or is simply a regular (non-member) function, then you don't need an instance pointer at all. You would just do:
boost::thread* thr = new boost::thread(some_regular_function);
As others mentioned, when you want to call an object method in a new thread, you have to supply the address of that object. But you don't need to call boost::bind, you can use the overloaded boost::thread constructor like this:
GUIThread = new boost::thread(&Main::MainThreadFunc, GUIMain);
If the method is in the same class you use this to get the address of the current instance, e.g.:
t = new boost::thread(&myclass::compute, this);
If the method has parameters, you can specify them after the second argument, e.g.:
t = new boost::thread(&myclass::compute, this, p1, p2);
boost::bind is your friend (it can sometimes have a rough way of showing it though)!
use GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain));
and then make your MainThreadFunc a regular member. That means that you can use the instance variables directly like you would normally do.
Something like this:
class GUIMain {
public:
GUIMain() : m_Member(42) {}
void MainThreadFunc() {
// use all members as you would normally do
std::cout << m_Member << std::endl;
}
private:
int m_Member;
};
In cases like this it is useful to think of non-static member functions as free functions that take the this as first parameter, for example in your case void MainThreadFunc(Main* this).
boost::thread accepts a nullary functor, so you have to pass it a nullary functor which contains a reference to the instance GUIMain and calls GUIMain->MainThreadFunc which, seen as I explained above, would be something like MainThreadFunc(GUIMain).
Boost (and now also C++ with TR1) provides helpers to create such functors, namely boost::bind (or alternatively boost::lambda::bind). The expression boost::bind(f, arg1, arg2, ...) means "return a nullary functor which calls f(arg1, arg2, ...)".
That said, you can use the following expression to create the thread:
GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain))
If your object is a functor, i.e. has an operator(), you can pass an instance of it to boost::thread. The operator() does not need to be static. For example:
#include <boost/thread.hpp>
struct th {
void operator()();
};
void th::operator()()
{
for (;;) {
// stuff
}
}
int main()
{
th t;
boost::thread my_thread( t ); // takes a copy of t !
my_thread.join(); // blocks
return 0;
}
So I want to have a simple multithreaded program that can pass by reference (or as a pointer) to the thread functions. I can't seem to do it in a way that works. How would I code it correctly so that it compiles?
#include <iostream>
#include <thread>
using namespace std;
class MyClass
{
int x;
public:
MyClass()
{
x = 10;
}
};
void foo(MyClass* c)
{
cout << "This is it" << endl;
}
int main()
{
MyClass c();
thread t1(foo, &c);
t1.join();
return 0;
}
The thread function needs to be able to access the MyClass object in order to record and get data. Is this even possible? How can this be done?
EDIT: What I ultimately need to have happen is for any changes made to the class object 'c' in the thread to actually happen in that same instance of the object. This program will later be elaborated upon to run several threads all accessing that one instance of the MyClass object. So if there is another way to do this without using references or pointers, or whatever, please let me know!
You need to declare c as
MyClass c;
When you add the parens it looks like the declaration of a function called c that takes no parameters and returns a MyClass object; this is known as the Most Vexing Parse.
What's the difference between a class function and global function with regard to function pointers in C++? I'm asking as the Windows CreateThread method doesn't seem to accept the function that the thread code goes in if the function is a class member.
I can pass the function (that the thread code goes in) to the CreateThread message when it is a global method, but once I make it a member of a class I get the error "argument of type [method layout] is incompatible with parameter of type LPTHREAD_START_ROUTINE". ClassName::* is in the middle now; is this affecting it?
What is the way around this?
Member function pointers (DWORD(WINAPI Foo::*)(LPVOID)) are different types than function pointers (DWORD(WINAPI *)(LPVOID)). Member functions have a hidden this parameter, causing a signature mismatch.
The easiest way to do this is to use C++11's <thread> header:
struct Foo {
void threadProc() {}
};
int main() {
Foo foo;
std::thread t{&Foo::threadProc, foo, /*other arguments to threadProc*/};
t.join();
}
If you have to resort to CreateThread, make use of the void * parameter to pass the instance:
struct Foo {
DWORD threadProc() {...}
};
extern "C" DWORD WINAPI proxyThreadProc(LPVOID userData) {
auto foo = static_cast<Foo *>(userData);
if (foo) {foo->threadProc();}
}
int main() {
Foo foo;
CreateThread(..., proxyThreadProc, &foo, ...);
}
The one in your class can now be pretty much whatever you want (like a std::function) and still work, as long as it's called with the right arguments from within the proxy procedure.
yeah, as #chris said there is a hidden pointer of this which will be connected by the end of parameters. when the thread carry out that, it don't know to match with a pointer in the position of the last parameter, then it failed to recover the heap of this function when finished, so It's banned to use non-static member function of class to drive a thread function except for the global function or static member function of class.
Ok so often times I have seen the following type of event handling used:
Connect(objectToUse, MyClass::MyMemberFunction);
for some sort of event handling where objectToUse is of the type MyClass. My question is how exactly this works. How would you convert this to something that would do objectToUse->MyMemberFunction()
Does the MyClass::MyMemberFunction give an offset from the beginning of the class that can then be used as a function pointer?
In addition to Mats' answer, I'll give you a short example of how you can use a non-static member function in this type of thing. If you're not familiar with pointers to member functions, you may want to check out the FAQ first.
Then, consider this (rather simplistic) example:
class MyClass
{
public:
int Mult(int x)
{
return (x * x);
}
int Add(int x)
{
return (x + x);
}
};
int Invoke(MyClass *obj, int (MyClass::*f)(int), int x)
{ // invokes a member function of MyClass that accepts an int and returns an int
// on the object 'obj' and returns.
return obj->*f(x);
}
int main(int, char **)
{
MyClass x;
int nine = Invoke(&x, MyClass::Mult, 3);
int six = Invoke(&x, MyClass::Add, 3);
std::cout << "nine = " << nine << std::endl;
std::cout << "six = " << six << std::endl;
return 0;
}
Typically, this uses a static member function (that takes a pointer as an argument), in which case the the objectToUse is passed in as a parameter, and the MyMemberFunction would use objectToUse to set up a pointer to a MyClass object and use that to refer to member variables and member functions.
In this case Connect will contain something like this:
void Connect(void *objectToUse, void (*f)(void *obj))
{
...
f(objectToUse);
...
}
[It is also quite possible that f and objectToUse are saved away somewhere to be used later, rather than actually inside Connnect, but the call would look the same in that case too - just from some other function called as a consequence of the event that this function is supposed to be called for].
It's also POSSIBLE to use a pointer to member function, but it's quite complex, and not at all easy to "get right" - both when it comes to syntax and "when and how you can use it correctly". See more here.
In this case, Connect would look somewhat like this:
void Connect(MyClass *objectToUse, void (Myclass::*f)())
{
...
objectToUse->*f();
...
}
It is highly likely that templates are used, as if the "MyClass" is known in the Connect class, it would be pretty pointless to have a function pointer. A virtual function would be a much better choice.
Given the right circumstances, you can also use virtual functions as member function pointers, but it requires the compiler/environment to "play along". Here's some more details on that subject [which I've got no personal experience at all of: Pointers to virtual member functions. How does it work?
Vlad also points out Functors, which is an object wrapping a function, allowing for an object with a specific behaviour to be passed in as a "function object". Typically this involves a predefined member function or an operatorXX which is called as part of the processing in the function that needs to call back into the code.
C++11 allows for "Lambda functions", which is functions declared on the fly in the code, that doesn't have a name. This is something I haven't used at all, so I can't really comment further on this - I've read about it, but not had a need to use it in my (hobby) programming - most of my working life is with C, rather than C++ although I have worked for 5 years with C++ too.
I might be wrong here, but as far as I understand,
In C++, functions with the same signature are equal.
C++ member functions with n parameters are actually normal functions with n+1 parameters. In other words, void MyClass::Method( int i ) is in effect void (some type)function( MyClass *ptr, int i).
So therefore, I think the way Connect would work behind the scenes is to cast the member method signature to a normal function signature. It would also need a pointer to the instance to actually make the connection work, which is why it would need objectToUse
In other words, it would essentially be using pointers to functions and casting them to a more generic type until it can be called with the parameters supplied and the additional parameter, which is the pointer to the instance of the object
If the method is static, then a pointer to an instance doesn't make sense and its a straight type conversion. I have not figured out the intricacies involved with non-static methods yet - a look at the internals of boost::bind is probably what you want to do to understand that :) Here is how it would work for a static function.
#include <iostream>
#include <string>
void sayhi( std::string const& str )
{
std::cout<<"function says hi "<<str<<"\n";
}
struct A
{
static void sayhi( std::string const& str )
{
std::cout<<"A says hi "<<str<<"\n";
}
};
int main()
{
typedef void (*funptr)(std::string const&);
funptr hello = sayhi;
hello("you"); //function says...
hello = (&A::sayhi); //This is how Connect would work with a static method
hello("you"); //A says...
return 0;
}
For event handling or callbacks, they usually take two parameters - a callback function and a userdata argument. The callback function's signature would have userdata as one of the parameters.
The code which invokes the event or callback would invoke the function directly with the userdata argument. Something like this for example:
eventCallbackFunction(userData);
In your event handling or callback function, you can choose to use the userdata to do anything you would like.
Since the function needs to be callable directly without an object, it can either be a global function or a static method of a class (which does not need an object pointer).
A static method has limitations that it can only access static member variables and call other static methods (since it does not have the this pointer). That is where userData can be used to get the object pointer.
With all this mind, take a look at the following example code snippet:
class MyClass
{
...
public:
static MyStaticMethod(void* userData)
{
// You can access only static members here
MyClass* myObj = (MyClass*)userdata;
myObj->MyMemberMethod();
}
void MyMemberMethod()
{
// Access any non-static members here as well
...
}
...
...
};
MyClass myObject;
Connect(myObject, MyClass::MyStaticMethod);
As you can see you can access even member variables and methods as part of the event handling if you could make a static method which would be invoked first which would chain the call to a member method using the object pointer (retrieved from userData).
So I have done some research, and have found you can create a boost::thread object and have it start with a non-static class function by using "this" and boost::bind etc. It really doesn't make much sense to me and all the examples I could find had the boost::thread object launched within the same class as the function it was starting with so this could be used. I however, am launching the thread in a different class so I'm afraid by using "this", I will be saying the "this" is from the class I am creating the thread from, rather than the one the function is in (I'm probably wrong, I need to learn more about this "this" guy). Here is an example of my source I am having the problem with.
ANNGUI.h
class ANNGUI
{
private:
boost::thread *GUIThread;
Main *GUIMain;
public:
// Creates the entire GUI and all sub-parts.
int CreateGUI();
}
ANNGUI.cpp
int ANNGUI::CreateGUI()
{
GUIMain = new Main();
GUIThread = new boost::thread(GUIMain->MainThreadFunc);
};
This isn't all the source, but I think my problem is in here somewhere, I know I have to deal with the "this" somehow, but I'm unsure how. I Could use a static function, but I didn't really want to make my variables static either.
Thanks.
Also, Is there any very good resource for using any boost libraries? Their web site documentation seems good, but over my head.
The this keyword is used with boost::bind when the function object you're creating is bound to a object member function. Member functions can't exist apart from instances, so when creating a functor object out of a member function with boost::bind, you need a pointer to an instance. That's exactly what the this keyword actually is. If you use the this keyword within a member function of a class, what you get is a pointer to the current instance of that class.
If you were to call bind from outside a class member function, you might say something like:
int main()
{
Foo f;
boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, &f));
}
Here, we're using Foo::some_function as our thread function. But we can't use this because we're calling bind from main. But the same thing could be achieved using this if we called bind from within a member function of Foo, like so:
void Foo::func1()
{
boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, this));
}
If a member function is static, or is simply a regular (non-member) function, then you don't need an instance pointer at all. You would just do:
boost::thread* thr = new boost::thread(some_regular_function);
As others mentioned, when you want to call an object method in a new thread, you have to supply the address of that object. But you don't need to call boost::bind, you can use the overloaded boost::thread constructor like this:
GUIThread = new boost::thread(&Main::MainThreadFunc, GUIMain);
If the method is in the same class you use this to get the address of the current instance, e.g.:
t = new boost::thread(&myclass::compute, this);
If the method has parameters, you can specify them after the second argument, e.g.:
t = new boost::thread(&myclass::compute, this, p1, p2);
boost::bind is your friend (it can sometimes have a rough way of showing it though)!
use GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain));
and then make your MainThreadFunc a regular member. That means that you can use the instance variables directly like you would normally do.
Something like this:
class GUIMain {
public:
GUIMain() : m_Member(42) {}
void MainThreadFunc() {
// use all members as you would normally do
std::cout << m_Member << std::endl;
}
private:
int m_Member;
};
In cases like this it is useful to think of non-static member functions as free functions that take the this as first parameter, for example in your case void MainThreadFunc(Main* this).
boost::thread accepts a nullary functor, so you have to pass it a nullary functor which contains a reference to the instance GUIMain and calls GUIMain->MainThreadFunc which, seen as I explained above, would be something like MainThreadFunc(GUIMain).
Boost (and now also C++ with TR1) provides helpers to create such functors, namely boost::bind (or alternatively boost::lambda::bind). The expression boost::bind(f, arg1, arg2, ...) means "return a nullary functor which calls f(arg1, arg2, ...)".
That said, you can use the following expression to create the thread:
GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain))
If your object is a functor, i.e. has an operator(), you can pass an instance of it to boost::thread. The operator() does not need to be static. For example:
#include <boost/thread.hpp>
struct th {
void operator()();
};
void th::operator()()
{
for (;;) {
// stuff
}
}
int main()
{
th t;
boost::thread my_thread( t ); // takes a copy of t !
my_thread.join(); // blocks
return 0;
}