[英]Calling a class member function from a thread using pthread_create
Below is the code 下面是代码
#include <iostream>
#include <pthread.h>
using namespace std;
class Base
{
private:
public:
void *threadCall1( void * value)
{
cout<<"inside threadCall1"<<endl;
}
protected:
};
class Derived
{
private:
public:
void *threadCall2 ();
protected:
};
void *Derived::threadCall2()
{
cout<<"inside threadCall2"<<endl;
}
int main ()
{
int k = 2;
pthread_t t1;
cout<<"inside main"<<endl;
Base *b = new Base();
pthread_create(&t1,NULL,&b->threadCall1,(void *)k);
return 0;
}
Error 错误
main.cc: In function
int main()': main.cc:46: error: ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say
main.cc:在函数int main()': main.cc:46: error: ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say
int main()': main.cc:46: error: ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say
&Base::threadCall1' main.cc:46: error: cannot convertvoid*(Base::*)(void*)' to
void*( )(void )' for argument3' to
int pthread_create(pthread_t*, const pthread_attr_t*, void*( )(void ), void*)'int main()': main.cc:46: error: ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say
&Base :: threadCall1'main.cc:46:错误:无法将参数3' to
void*(Base::*)(void*)' to
void *( )(void )3' to
int pthread_create(pthread_t *,const pthread_attr_t *,void *( )(void ),void *)'
I agree C++ forbids this call but is there any way I can call a class member function using posix thread 我同意C ++禁止此调用,但是有什么方法可以使用posix线程调用类成员函数。
There's no such thing as &b->threadCall1
. 没有&b->threadCall1
这样的东西。 Fortunately, pthread allows you to pass a void ptr to the class (the one you're filling with k). 幸运的是,pthread允许您将一个无效的ptr传递给该类(用k填充的那个)。 Pass b
as this void ptr to a global (or static member) function that simply calls b->threadCall1();
将b
作为此void ptr传递给简单调用b->threadCall1();
的全局(或静态成员)函数b->threadCall1();
then move k to an attribute of Base instead of an argument of Base::threadCall1(). 然后将k移至Base的属性,而不是Base :: threadCall1()的参数。
You can do this via a function that dispatches the work accordingly: 您可以通过相应地分派工作的函数来做到这一点:
#include <iostream>
#include <pthread.h>
struct Base {
virtual void work() {
std::cout << "Base::work()\n";
}
virtual ~Base() {}
};
struct Derived : public Base {
void work() override {
std::cout << "Derived::work()\n";
}
};
void* thread_adapter(void* obj) {
Base* p = static_cast<Base*>(obj);
p->work();
return nullptr;
}
int main() {
Derived d;
pthread_t thread;
pthread_create(&thread, nullptr, thread_adapter, &d);
pthread_join(thread, nullptr);
}
pthread_create
accepts a pointer to arbitrary data for the thread function. pthread_create
接受一个指向线程函数任意数据的指针。 Pass the address of your object, and use a forwarding function such as the thread_adapter
defined above. 传递对象的地址,并使用转发功能,例如上面定义的thread_adapter
。 Inside the adapter function, you can static_cast
the argument back to a Base*
inside your thread function and invoke the member function as desired. 在适配器函数内部,您可以将参数static_cast
返回到线程函数内部的Base*
并根据需要调用成员函数。
However, you may want to look into the std::thread library, which supports such operations in a more natural way: 但是,您可能需要研究std :: thread库,该库以更自然的方式支持此类操作:
#include <iostream>
#include <thread>
struct Base {
virtual void work() {
std::cout << "Base::work()\n";
}
virtual ~Base() {}
};
struct Derived : public Base {
void work() override {
std::cout << "Derived::work()\n";
}
};
int main() {
Derived d;
std::thread t(&Base::work, d);
t.join();
}
You cannot use pointer to member function as thread routine. 您不能将指向成员函数的指针用作线程例程。 Consider to use thead context structure to pass need information to the thead routine: 考虑使用thead上下文结构将需要的信息传递给thead例程:
struct thread_context {
Base* object;
void (Base::*func)(void*);
};
void *thread_routine(void *arg) {
thread_context* context = static_cast<thread_context*>(arg);
context->object->(*context->func)(nullptr);
...
}
...
thread_context context = {
b1,
&Base::threadCall1
};
pthread_create(&t1,NULL,&thead_routine, &context);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.