Reputation:
I'm using pthread to create threads (in c++ application):
int result = pthread_create( &thread, NULL, CMyClass::RunThread, 0);
and CMyClass::RunThread must be static function (in order to be compile):
static void *RunThread(void *ptr);
so all the class members and helper functions which are being called from RunThread, must be static too.
It seem that I have to many (~5) static members. (seem not a good programming to me...)
Is there a better way ? more elegant way ?
thanks
Upvotes: 3
Views: 164
Reputation: 4725
I do this quite often and therefore, I have created a small pattern for executing member functions
#include <pthread.h>
#include <iostream>
template<class T, void*(T::*thread_func)(void*)>
class pthread_launcher {
public:
pthread_launcher(T* obj=NULL, void* arg=NULL) : _obj(obj), _arg(arg) {}
void *launch() { return (_obj->*thread_func)(_arg);}
private:
/// Object pointer
T* _obj;
/// Command argument for member function
void *_arg;
};
// Launch thread function
template<class T>
void *launch_member_function(void *obj)
{
T* launcher = reinterpret_cast<T*>(obj);
return launcher->launch();
}
typedef struct thread_arg {
float fData;
} thread_arg_t;
class A {
public:
void* nonStaticFunction(void* arg) {
std::cout << "Executing" << std::endl;
return NULL;
}
};
// (1)
template class pthread_launcher<A,&A::nonStaticFunction>;
int main() {
thread_arg_t arg;
arg.fData = 1.0f;
// Laucher (2)
pthread_launcher<A, &A::nonStaticFunction> launcher;
// Initialize using function pointer and optional argument (2)
launcher = pthread_launcher<A,&A::nonStaticFunction>(&a, &arg);
A a;
pthread_t thread;
// Start thread (4)
pthread_create(&thread, NULL,
launch_member_function<pthread_launcher<A,&A::nonStaticFunction> >,
&launcher);
pthread_join(thread,NULL);
return 0;
}
The only thing you need to do over and over again, is what happens at (1), (2), (3) and (4).
Upvotes: 0
Reputation: 3911
The pseudo code looks like this:
// static stub function
void* MyClass::thread_stub(void* p) {
MyClass* c = static_cast<MyClass*>(p);
return c->thread_func();
}
void* MyClass::thread_func() {
return NULL;
}
int MyClass::start() {
pthread_create(....thread_stub, this);
}
Upvotes: 1