C++ 在类里面使用多线程技术

C++_杂篇 同时被 2 个专栏收录
46 篇文章 0 订阅
16 篇文章 0 订阅

前言

有很多时候,我们希望可以在C++类里面对那些比较耗时的函数使用多线程技术,但是熟悉C++对象语法的人应该知道,C++类的成员函数的函数指针不能直接做为参数传到pthread_create,主要因为是C++成员函数指针带有类命名空间,同时成员函数末尾是会被C++编译器加上可以接收对象地址的this指针参数。因此需要将成员函数做一定的转化,将其转化为不被编译器加上this指针,而由我们自己来为该函数维护"this"指针即可。

举例分析

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <time.h>
using namespace std;
class Test
{
	public:
		int sum=0;
		int cnt;
	public:
		int insert();
};
int Test::insert()
{
	sleep(2);
	cnt+=1;
}

如上所示,代码声明了一个类Test,假设该类有一个十分耗时的成员函数:insert(),这个求和函数每次执行需要2000ms的时间。对于如此耗时的函数,我们在设计时都会想方法将其设计为线程函数,这样调用者才不会阻塞。
于是我们为其加上多线程:

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
using namespace std;
class Test
{
	public:
		int sum=0;
		int cnt;
	public:
		int insert();
		void * insert_pth(void*);
		void lanch();
};
int Test::insert()
{
	sleep(2);
	sum+=1;
}
void * Test::insert_pth(void*)
{
	insert();
}
void Test::lanch()
{
	pthread_t pth;
	pthread_create(&pth,NULL,insert_pth,NULL);
}
int main()
{
	Test t;
	t.lanch();
	return 0;
}

以上代码通过调用lanch()来创建多线程来执行insert_pth,insert_pth 再调用insert().
但是 这样的代码在编译时即会报错。

pthread.cpp: In member function ‘void Test::lanch()’:
pthread.cpp:30:42: error: invalid use of non-static member function
  pthread_create(&pth,NULL,insert_pth,NULL);

只需将insert_pth变化为static函数,同时将insert逻辑代码转移到insert_pth即可

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
using namespace std;
class Test
{
	public:
		int sum=0;
		int cnt;
	public:
		int insert();
	static 	void * insert_pth(void*);
		void lanch();
};
int Test::insert()
{
	sleep(2);
	sum+=1;
	printf("%d insert.....\n",sum);
}
void * Test::insert_pth(void* __this)
{
	Test * _this =(Test *)__this;
	sleep(2);
	_this->sum+=1;
	printf("%d insert.....\n",_this->sum);
}
void Test::lanch()
{
	pthread_t pth;
	pthread_create(&pth,NULL,insert_pth,(void*)this);
}
int main()
{
	Test t;
	t.sum=0;
	t.lanch();
	sleep(5);
	return 0;
}

总结

使用多线程处理耗时成员函数的步骤:

  1. 声明另外一个静态函数:static void *XXX_pth(void* __this);
    该函数与目标成员函数在函数名尽量保持一致
  2. 将原成员函数的代码拷贝至void * XXX_pth(void * __this);
    在 XXX_pth()开始处将void * __this 转化为 对象的指针ObjectPoint * _this;
    将拷贝下来的所有成员变量加上 _this->
  3. 编写线程启动代码。
    注意pthread_create()最后一个参数传入this指针

注意

在 XXX_pth()函数内容不要调用类的其它成员函数,否则成员函数将无法获取正确的this指针而操作错误内存,从而导致segmantation fault.
  • 7
    点赞
  • 3
    评论
  • 15
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

评论3
请先登录 后发表评论~
©️2021 CSDN 皮肤主题: 点我我会动 设计师:白松林 返回首页

打赏作者

Icoding_F2014

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值