为什么在C++中使用pthread

为什么在C++中使用pthread,第1张

static void* worker(void *arg)

1、worker函数的作用只是用来调用run()函数,那么为什么不直接用run()函数,而要借用worker函数多此一举呢?

2、为什么worker()函数一定要是静态成员函数呢?

这就是C++和C不一样的地方了

首先,我们来思考一下,这个run()函数的功能是什么?

正如上图的注释写到的那样:“ /*工作线程执行的函数,不断从工作队列中取出任务并执行*/ ” !

既然如此,run()如果按照C语言里面的写法,可以直接写成线程的执行函数了,如下:

/*pthread_create()定义如下*/
/*int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);*/

/*线程执行函数*/
void * run(void *arg){
    ....
    return NULL;
}

int main(){
    
    /*创建子线程*/
    pthread_create(&fd,NULL,run,NULL);
    
    return 0;
}

如果C++和C没有区别的话,写到这里也就万事大吉了,但是,事情没有这么简单。

回忆一下,我们知道,C++类内的成员变量和成员函数是分别存放的,类内成员函数在内存中只有一份,类的所有实例都是访问这一份内存来调用同一成员函数的,那么问题来了,这个成员函数是怎么知道是哪份实例在调用自己的呢?是张三调用自己还是李四调用自己呢?

一门编程语言肯定要能够自圆其说,而this指针可以用来解决这个问题!!我们知道,C++类内非静态成员函数的第一个参数其实是隐藏的this指针:T* const register this,这个指针指向调用该非静态成员函数的对象实例,这样的话,非静态成员函数就能够知道是哪个实例在调用自己。

回到上面线程执行函数这个话题,在游双的书中,线程执行函数run()是在类内的,所以它的第一个默认参数是this指针,而pthread_create()第三个参数只接受唯一的一个void* 参数,但是加上this指针,一共两个参数,所以线程执行函数会出错。

那么我们就要想办法解决这个问题了,既然在这个地方this指针不被欢迎,那我们就丢掉它,正巧,静态成员函数没有this指针,因为静态成员函数独立于任何实例对象,也就是所有实例对象在调用它的时候,它并不需要区分是谁在调用自己。

貌似到这里柳暗花明了,我们是不是只需要把run()定义为静态成员函数就行了呢?

很可惜,答案是否定的。

正因为静态成员函数没有this指针,不知道应该访问哪个对象中的数据,所以在程序中不可以用静态成员函数直接访问类中的动态成员(包括非静态成员函数和非静态成员变量),而要达到此目的,只能通过两种方式实现:

  1. 通过类的静态对象来调用。比如单例模式中,静态函数可以通过类的全局唯一实例了来访问动态成员函数。
  2. 将类的对象作为参数传递给该静态函数,然后在静态函数中引用这个对象,并调用其动态方法。

书中使用的便是第二中方法:创建一个静态成员函数worker(),然后在worker()里面调用run(),这下就解释了开头的两个问题

至此,所有的疑惑都已烟消云散!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/langs/3002855.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-09-27
下一篇 2022-09-27

发表评论

登录后才能评论

评论列表(0条)

保存