为什么在C++中使用pthread_create函数时,该函数第三个参数必须指向一个静态函数

本文探讨了C++中为何使用静态成员函数worker调用run来创建线程的原因。主要问题是静态成员函数没有this指针,不能直接访问非静态成员,而worker函数作为线程入口,通过传入类对象实例解决了这个问题。总结了静态成员函数在线程创建中的作用及其限制,并提出了两种解决静态成员函数访问动态成员的方法。
摘要由CSDN通过智能技术生成

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(),这下就解释了开头的两个问题

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

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值