如何在C++类中使用非static的pthread线程函数访问类成员
解决C++类中线程函数访问成员变量的问题
这个问题其实是C++类成员函数和C风格线程API(pthread)之间的常见适配问题——非static成员函数因为隐含this指针,签名和pthread_create要求的void*(*)(void*)不匹配,所以没法直接用。下面给你两种靠谱的解决思路,都能让你不用把业务逻辑函数设为static,同时正常访问类的所有成员:
方法一:Static包装器 + 传递this指针(兼容C++98及以上)
这是最经典的解决方案,核心思路是用一个static函数作为pthread的入口,然后把当前对象的this指针传递给线程,在static函数里转成类指针后调用实际的非static业务函数。
修改后的完整代码:
#include <iostream> #include <pthread.h> using namespace std; class Base{ private: // 仅作为pthread入口的static包装函数 static void * fpga_read_wrapper(void* arg); // 实际的线程逻辑,非static,可自由访问类成员 void fpga_read_impl(); void foo_2(); public: void foo(void); protected: int b = 10; // 赋值方便测试 }; void Base::foo(void) { pthread_t id; // 将当前对象的this指针作为参数传入线程 pthread_create(&id, NULL, fpga_read_wrapper, this); cout << "\nInside base class" << endl; } // static包装函数:转换参数类型,调用实际业务函数 void * Base::fpga_read_wrapper(void *arg) { Base* self = static_cast<Base*>(arg); self->fpga_read_impl(); return NULL; } // 非static的线程业务函数,正常访问类成员 void Base::fpga_read_impl() { cout << "\nInside thread function " << endl; cout << "Value of B inside thread class: " << b << endl; // 可以直接调用其他成员函数 // foo_2(); } int main() { Base a; a.foo(); // 等待线程执行完毕再退出,避免主线程提前结束 pthread_exit(NULL); return 0; }
原理说明:
pthread_create的最后一个参数允许我们传递任意void*类型的数据,这里我们把当前对象的this传进去- static包装函数拿到这个指针后,转换为
Base*类型,就可以像普通对象一样调用非static成员函数 - 因为static函数是类的成员,所以有权限访问类的private/protected成员
方法二:使用C++11的std::thread(更简洁)
如果你的项目支持C++11及以上标准,用std::thread可以完全避免写static包装函数,直接通过lambda捕获this来调用非static成员函数:
#include <iostream> #include <thread> using namespace std; class Base{ private: // 直接定义非static的线程业务函数 void fpga_read(); void foo_2(); public: void foo(void); protected: int b = 10; }; void Base::foo(void) { // lambda捕获this,直接调用非static成员函数 thread t([this](){ fpga_read(); }); cout << "\nInside base class" << endl; t.join(); // 等待线程执行完成 } void Base::fpga_read() { cout << "\nInside thread function " << endl; cout << "Value of B inside thread class: " << b << endl; // foo_2(); } int main() { Base a; a.foo(); return 0; }
原理说明:
std::thread支持接收任意可调用对象,lambda表达式捕获this后,就可以在lambda内部直接调用类的非static成员函数- 这种方式代码更简洁,不需要额外的包装函数,是C++11以后推荐的写法
内容的提问来源于stack exchange,提问作者Gagandeep
相关产品推荐
相关产品推荐

