I\'m wondering the best way to start a pthread that is a member of a C++ class? My own approach follows as an answer...
This can be simply done by using the boost library, like this:
#include <boost/thread.hpp>
// define class to model or control a particular kind of widget
class cWidget
{
public:
void Run();
}
// construct an instance of the widget modeller or controller
cWidget theWidget;
// start new thread by invoking method run on theWidget instance
boost::thread* pThread = new boost::thread(
&cWidget::Run, // pointer to member function to execute in thread
&theWidget); // pointer to instance of class
Notes:
In C++11 you can do the same but without boost
// define class to model or control a particular kind of widget
class cWidget
{
public:
void Run();
}
// construct an instance of the widget modeller or controller
cWidget theWidget;
// start new thread by invoking method run on theWidget instance
std::thread * pThread = new std::thread(
&cWidget::Run, // pointer to member function to execute in thread
&theWidget); // pointer to instance of class
I have used three of the methods outlined above. When I first used threading in c++ I used static member functions, then friend functions and finally the BOOST libraries. Currently I prefer BOOST. Over the past several years I've become quite the BOOST bigot.
BOOST is to C++ as CPAN is to Perl. :)
I usually use a static member function of the class, and use a pointer to the class as the void * parameter. That function can then either perform thread processing, or call another non-static member function with the class reference. That function can then reference all class members without awkward syntax.
The boost library provides a copy mechanism, which helps to transfer object information to the new thread. In the other boost example boost::bind will be copied with a pointer, which is also just copied. So you'll have to take care for the validity of your object to prevent a dangling pointer. If you implement the operator() and provide a copy constructor instead and pass the object directly, you don't have to care about it.
A much nicer solution, which prevents a lot of trouble:
#include <boost/thread.hpp>
class MyClass {
public:
MyClass(int i);
MyClass(const MyClass& myClass); // Copy-Constructor
void operator()() const; // entry point for the new thread
virtual void doSomething(); // Now you can use virtual functions
private:
int i; // and also fields very easily
};
MyClass clazz(1);
// Passing the object directly will create a copy internally
// Now you don't have to worry about the validity of the clazz object above
// after starting the other thread
// The operator() will be executed for the new thread.
boost::thread thread(clazz); // create the object on the stack
The other boost example creates the thread object on the heap, although there is no sense to do it.
You have to bootstrap it using the void* parameter:
class A { static void* StaticThreadProc(void *arg) { return reinterpret_cast<A*>(arg)->ThreadProc(); } void* ThreadProc(void) { // do stuff } }; ... pthread_t theThread; pthread_create(&theThread, NULL, &A::StaticThreadProc, this);