类成员函数创建线程

30 篇文章 0 订阅

参考:http://blog.csdn.net/braveyly/article/details/3446472

对于”在类里面的成员函数创建线程怎么搞“都有两三个月的疑问了,一直没想到什么好的方法。对于创建线程的调用函数归属问题不太清楚,也没什么时间做个实验。

下面的实验借鉴链接中的博客的思想,实验环境为ubuntu 11.04, Emacs。

补充:

Linux下,创建线程为:pthread_create();           回调函数的形式为:void * thread_proc(void * arg);

Windows下,创建线程为:CreateThread();      回调函数形式为:DWORD WINAPI thread_proc(LPVOID lpParam);  

一共有三种方法:

1. 这种情况,一般是将线程函数申明为静态成员变量,写入口函数时,指明该入口函数所在的类

在类中定义的成员函数,VC在编译时会强加一个this指针,通过函数名无法定位该入口函数。将该成员函数声明为static类型,可以将this指针除去。

缺点:static成员函数只能访问static成员。

在类A的成员函数中创建线程,代码如下:

pthread_t threadID;

int err=pthread_create(&threadID, NULL, A::thread_proc, NULL);

声明时:

class A

{

static void * thread_proc(void * arg);

};

注意:入口函数的输出类型和输入类型不能变化。

2. 以将线程函数申明成友员函数, 这样可以传入该类的指针,访问类的成员; 

注意:友元函数在头文件中声明,在cpp文件中定义。如果直接定义在头文件中,链接的时候会有多重定义错误提示。

3. 可以对成员函数实现回调,并访问非静态成员的。

这种方法充分利用了传给回调函数的指针,将类中的成员打包发送给了回调函数,从而实现访问。

(下面没有进行试验,部分需要改动)

如下所示,这是为了实现线程函数访问类成员而实现的类。比MFC的实现方法好象要好一点。

class base;

//?
typedef int (base::*fnCallBack)(void *p); 

//用来封装回调类的信息
struct callback
{
	void *param;
	fnCallBack *pfuc;		
	base *pThis;			//存放类的信息
};

class base
{
	//回调函数,没有试验,但应该按照回调函数的标准来定义
	static int myThreadfuc(void * p)
	{ 
		struct callback *p1=(struct callback *)p; 
		
		//将封装后的信息解包
		base * pthis=p1->base;
		fnCallBack *pfuc=p1->pfuc;
		void * param=p1->param;

		//运行实际要运行的函数
		int i=(pthis->*pfuc)(param);
		delete p;
		
		return i; 
     } 
public: 
	void myCreateThread(fnCallBack pfuc,void *param)
	{
		struct callback *p=new struct callback; 

		//把封装后的类的成员以及回调函数打包
		p.param=param;				//客户要传给实际要运行函数的参数
		p.pThis=this;				//保存类的指针
		p.pfuc=pfuc;				//保存实际要运行的函数
		
		//创建线程,注意其他参数自己补全
		::CreateThread(myThreadfuc,p); 
     }

	virtual int myCallBack(void *p)
	{
		printf("It's base class./n");
		return 0;
	}
};

class derived:public base
{
	int myCallBack(void *p)
	{
		printf("It's derived class/n");
	}
}; 

void myCreateThreadImitate(fnCallBack fuc,void *p) 
{ 
	(*fuc)(p);
} 

void main() 
{ 
	base p;
	char *param; 
	p.myCreateThread(&(base::myCallBack),param); 

	derived p2;
	p2.myCreateThread(&(base::myCallBack),param);  
}



在C++类中创建线程可以使用成员函数来实现,可以将成员函数作为数传递给线程函数进行调用。要创建一个线程,需要使用C++11标准库中的<thread>头文件中的std::thread。在成员函数创建线程,需要在函数定义前加上static关键字,因为非静态成员函数需要与的对象一起调用,而线程无法调用对象。如果函数不是静态的,则需要传递一个指向对象的指针作为函数数。 具体实现可以先定义一个static成员函数,该函数将作为线程函数,然后在该函数中调用成员函数。在创建线程时,可以使用std::thread构造函数,将该静态成员函数和对象指针作为数传递给std::thread对象。 例如: ``` #include <iostream> #include <thread> class MyClass { public: void myFunc() { std::cout << "This is myFunc." << std::endl; } static void threadFunc(MyClass* obj) { obj->myFunc(); } }; int main() { MyClass obj; std::thread myThread(&MyClass::threadFunc, &obj); myThread.join(); return 0; } ``` 在上面的例子中,我们定义了一个MyClass,其中包含一个成员函数myFunc。由于该函数需要在线程中调用,因此我们还定义了一个静态成员函数threadFunc,并在其中调用了myFunc。在main函数中,我们创建了一个MyClass对象obj,并将该对象指针传递给std::thread的构造函数。这将构造一个新的线程,并在新线程中调用threadFunc函数。最后,我们使用myThread.join()函数等待线程结束。 总之,在C++中,使用成员函数创建线程是非常方便和灵活的方法,可以使用这种方法在类中处理多线程任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值