i have a Base class and Derived class. they have a virtual function- virtual void action() how can i pass it to *pthread_create()* function?
example(with errors):
class Base{
protected:
pthread_t tid;
public:
virtual void* action() = 0;
};
class Derived : public Base{
void* action();
Derived(){
pthread_create(&tid, NULL, &action, NULL);
}
};
maybe it should be static? i tried lot of combinations but cant find solution..
I ran into this problem a couple months back working on my senior design project. It requires some knowledge of underlying C++ mechanics.
The underlying issue is that pointers to functions are different from pointers to member functions. This is because member functions have an implicit first parameter, this
.
From the man
page:
int pthread_create(pthread_t *thread,
const pthread_attr_t *attr,
void *(*start_routine) (void *),
void *arg);
The thread entrance point is a void* (*)(void*)
. Your function, Base::action
has the type void* (Base::*)()
. The Base::
part of that ugly type declaration denotes the type of this
. The type discrepancy is why the compiler won't accept your code.
There's two things we need to fix to make this work. We can't use a member function, because pointers to member functions don't bind this
to an instance. We also need a single parameter of type void*
. Thankfully, these two fixes go hand in hand because the solution is to explicitly pass this
ourselves.
class Base {
public:
virtual void* action() = 0;
protected:
pthread_t tid;
friend void* do_action(void* arg) {
return static_cast<Base*>(arg)->action();
}
};
class Derived : public Base {
public:
Derived() {
// This should be moved out of the constructor because this
// may (will?) be accessed before the constructor has finished.
// Because action is virtual, you can move this to a new member
// function of Base. This also means tid can be private.
pthread_create(&tid, NULL, &do_action, this);
}
virtual void* action();
};
Edit: Woops, if tid
is protected
or private
, then do_action
needs to be a friend
.
You have to have a function that takes one void pointer to pass to pthread_create
. I'd write the function myself, as a function that takes a pointer to Base
(Derived
would work as well), then call the action
function of the parameter. You can then create a thread that runs the function and received this
as parameter:
void *f(void *param)
{
Base* b = (Base *)param;
return b->action();
}
class Derived : public Base{
void* action();
Derived() {
pthread_create(&tid, NULL, f, this);
}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With