使用 pthread_create 从线程调用类成员函数
Calling a class member function from a thread using pthread_create
下面是代码
#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;
}
错误
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
&Base::threadCall1' main.cc:46:错误:不能 将void*(Base::*)(void*)' to
void*()(void)' 转换为参数3' to
int pthread_create(pthread_t*, const pthread_attr_t*, 无效*()(无效),无效*)'
我同意C++禁止此调用,但是有什么方法可以使用posix线程调用类成员函数
您可以通过相应地调度工作的函数来执行此操作:
#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
接受指向线程函数的任意数据的指针。传递对象的地址,并使用转发函数,例如上面定义的thread_adapter
。在适配器函数中,可以将参数static_cast
回线程函数中的Base*
,并根据需要调用成员函数。
但是,您可能希望查看 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();
}
现场示例
没有&b->threadCall1
这样的东西。幸运的是,pthread 允许您将一个空 ptr 传递给类(你用 k 填充的那个)。将b
作为此 void ptr 传递给全局(或静态成员)函数,该函数只需调用b->threadCall1();
然后将 k 移动到 Base 的属性而不是 Base::threadCall1() 的参数。
不能将指向成员函数的指针用作线程例程。考虑使用 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);
- 无法调用成员函数,尝试正确执行此操作仍然失败
- 在 transform() 中调用成员函数
- C++::在构造函数退出之前通过指针调用成员函数
- 为什么我可以通过野生指针调用成员函数
- 从 Qt 中的信号调用成员函数的问题
- 调用C++成员函数指针,而不知道哪个类
- 如何从嵌套在命名空间中的类调用成员函数?
- 无法在非成员函数中调用成员函数
- 为什么分配了 nullptr 的指针可以调用成员函数?
- 通过带有成员函数指针的 QHash 调用成员函数的正确方法
- 使用可变参数模板调用成员函数
- 调用成员对象的构造函数
- 有没有办法在没有括号的情况下在C++中调用成员的getter/setter?
- 如何调用成员初始化器列表中参考成员的构造函数
- 使用按引用调用时,不能在没有对象的情况下调用成员函数 const
- 如果绝对没有调用成员函数,是否允许使用不完整类型的向量?如果是这样,从什么时候开始
- 在另一个成员函数中调用成员函数时'int'之前的预期主表达式
- 为什么调用成员函数不调用该对象的 ODR-USE?
- 如何在模板参数中调用成员
- 是否可以使用 EXPECT_CALL 来验证模拟对象的构造函数是否在某些时候调用成员函数?