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...
So, I usually declare a friend function and have that call a public method that does what I want the thread to accomplish. Is this the best design practice, or should I be doing something else? Thx
Sorry for the obligatory comment, but have you considered using Boost instead?
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.
This can be simply done by pulling a couple things from the boost libraries, like this:
#include <boost/function.hpp>
#include <boost/thread.hpp>
class cMyClass
{
public:
void Run();
}
cMyClass theClass;
// start new thread by invoking method run on theClass instance
boost::thread* pThread = new boost::thread(
boost::bind(
&cMyClass::Run, // member function
&theClass ) ); // instance of class
Notes:
- This uses an ordinary class member function. There is no need to add extra, static members which confuse your class interface
- Just include boost/function.hpp and boost/thread.hpp in the source file where you start the thread. If you are just starting with boost, all the rest of that large and intimidating package can be ignored.
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. :)
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.