类成员函数创建线程

参考: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);  
}



你可能感兴趣的:(thread,struct,Class,callback,emacs,winapi)