背景: 有一些状态需要实时监控,因此需要新建一个线程来处理此事,为了方便维护,线程的调用函数使用线程创建所在类的类方法。 解决方案: 通过线程创建函数pthread_create实现,函数原型如下:
//参数依次是: 创建的线程id, 线程属性参数, 调用的函数地址, 传入的函数参数
int pthread_create (pthread_t * tidp, const pthread_attr_t * attr, void * (*start_rtn)(void*), void *arg)
点1:使用类方法作为线程的调用函数时,需要将类方法声明为静态方法:
static void* cartesianPose_operate_monitor(void* args);
点2:静态类方法中使用类成员变量时,一种方式是将成员变量同样声明为静态,但这样处理会给类成员变量的使用带来很大的不便,另一种方式是通过传递函数参数(即pthread_create 的第四个参数void *arg)实现,本文介绍的即是该方法。 具体实现函数:
//参数依次是:创建的线程id,线程属性参数,调用的函数地址,传入的函数参数
int ret1 = pthread_create(&tids1_, NULL, cartesianPose_operate_monitor, this); //this是重点
从上述函数实现可看到,第四个参数为当前的类对象指针this,通过该指针可以实现在类方法cartesianPose_operate_monitor中使用非静态类成员变量,具体实现如下:
//类定义
class classA {
public:
classA (int argc, char** argv);
~classA ();
private:
static void* cartesianPose_operate_monitor(void* args); //**point1**:声明为静态方法
private:
pthread_t tids1_;
bool xDecPressed_; //**point2**:声明为非静态bool
};
void* classA ::cartesianPose_operate_monitor(void* args)
{
classA * my_class = (classA *) args; //**point3**:将void*入参转为类对象classA* 指针
ros::Rate s_timer(ROS_LOOP_RATE); // 定时器
while(1)
{
s_timer.sleep();
if (my_class->xDecPressed_) //**point4**:通过类对象指针,使用非静态类成员变量
{
std::cout << "say hello" << std::endl;
}
}
}
classA ::classA (int argc, char** argv)
:xDecPressed_(false)
{
//参数依次是:创建的线程id,线程属性参数,调用的函数地址,传入的函数参数
int ret1 = pthread_create(&tids1_, NULL, cartesianPose_operate_monitor, this); //**point5**:线程创建,函数参数为this
}
通过以上步骤可以实现类创建、类方法作为线程调用函数和静态类方法中使用非静态类成员变量等操作。