成员函数作为线程函数调用

遇到的问题

         我们在编程中需要把数据封装成一个类,调用pthread_create 利用成员函数去创建一个线程往往是不成功的!

error: argumentof type ‘void* (Threadpool::)(void*)’ does not match ‘void* (*)(void*)’

出现类型不匹配的问题。因为pthread_create需要的参数类型为void*(*)(void*),而thread_rounter作为类的成员函数时其类型是void* (Threadpool::)(void*)的成员函数指针。我们知道类的成员函数在经过编译器处理之后,会变成带有this指针参数的全局函数,所以类型注定是不会匹配的。

解决方案

         天无绝人之路,尤其是对于C++这种被称为Wenger巨人刀(http://coolshell.cn/articles/6639.html#more-6639)的超级语言一定会有各种奇淫技巧提供出超乎想象的解决方案的。


各种编程语言的调侃图

声明static 成员函数作为线程函数

但是如果将thread_rounter声明为static类型,那么编译器会将static形式的函数,转换成不带this指针的全局函数,所以其类型可以与pthread_create需要的参数类型相匹配。但是类的静态成员函数无法访问类的非静态成员,不过这可以通过传递this指针解决这个问题。

staticvoid*threadfun(void*)

{

         //dosomething

}

通过全局函数回调成员函数

void *thread (void *tmp)/线程执行函数

{

  ClassName*p=( ClassName *)tmp;

   //通过p指针间接访问类的非静态成员

}

终极解决方案C++模板

//声明定义一个模板函数

template <typename TYPE, void(TYPE::*_RunThread)() >

void* _thread_t(void* param)

{

   TYPE* This = (TYPE*)param;

   This->_RunThread();

   return NULL;

}

/*

         _thread_t:为模板函数名,可随意起

         TYPE:类名

_ RunThread:为TYPE类中成员函数的名称,在这里必须是pbulic 。不可以任意取名。返回类型和参数必须和类中的一致。

*/

class MyClass

{

public:

   MyClass();

   void _RunThread();

private:

   pthread_t tid;

  

};

 

void MyClass::_RunThread()

{

   this->DoSomeThing();

   //...

}

 

MyClass::MyClass()

{

         //利用C++强大的模板功能巧妙滴实现了函数转换

   pthread_create(&tid, NULL, _thread_t<MyClass,&MyClass::_RunThread>, this);

}

 

     函数模版不单可以替换类型本身,还能替换类型的成员函数。

注意:1、名称只能是_RunThread,不能在指定模版参数的时候修改;

     2、_RunThread只能是public的,除非把_thread_t定义到MyClass的内部。

总结

         这些奇淫技巧没有必要记住,用的时候能想起来查的到即可。以上说做的工作就只有一个目的,把函数类型转换成 void*(*)(void*)类型的。同理可以把这种技巧移植到其他的需要的地方,比如可以把成员函数转换成 T(*)(T*)的函数,这里就不一一解释了。

         如果读者看到这里没有明白以上所说的是什么意思或者有点晕,没有关系,照猫画虎用就可以了。建议读者从新阅读C++教
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值