C++成员函数做为线程函数

网上找来的资料如下:

 

WIN32线程控制主要实现线程的创建、终止、挂起和恢复等操作,这些操作都依赖于WIN32提供的一组API和具体编译器的C运行时库函数。

 

1.线程函数

  在启动一个线程之前,必须为线程编写一个全局的线程函数,这个线程函数接受一个32位的LPVOID作为参数,返回一个UINT,线程函数的结构为:

UINT ThreadFunction(LPVOID pParam)

{

 //线程处理代码

 return0;

}

复制代码

  在线程处理代码部分通常包括一个死循环,该循环中先等待某事情的发生,再处理相关的工作:

while(1)

{

 WaitForSingleObject(,);//WaitForMultipleObjects()

 //Do something

}

复制代码

  一般来说,C++的类成员函数不能作为线程函数。这是因为在类中定义的成员函数,编译器会给其加上this指针。请看下列程序:

include "windows.h"

include <process.h>

class ExampleTask 

 public: 

  void taskmain(LPVOID param); 

  void StartTask(); 

}; 

void ExampleTask::taskmain(LPVOID param) 

{} 

void ExampleTask::StartTask() 

 _beginthread(taskmain,0,NULL);

int main(int argc, char* argv[])

{

 ExampleTask realTimeTask;

 realTimeTask.StartTask();

 return 0;

}

复制代码

  程序编译时出现如下错误:

error C2664: '_beginthread' : cannot convert parameter 1 from 'void (void *)' to 'void (__cdecl *)(void *)'

None of the functions with this name in scope match the target type 

 

  再看下列程序:

include "windows.h"

include <process.h>

class ExampleTask 

 public: 

  void taskmain(LPVOID param); 

}; 

void ExampleTask::taskmain(LPVOID param) 

{} 

int main(int argc, char* argv[])

{

 ExampleTask realTimeTask;

 _beginthread(ExampleTask::taskmain,0,NULL);

 return 0;

}

复制代码

  程序编译时会出错:

error C2664: '_beginthread' : cannot convert parameter 1 from 'void (void *)' to 'void (__cdecl *)(void *)'

None of the functions with this name in scope match the target type 

 

如果一定要以类成员函数作为线程函数,通常有如下解决方案:  (1)将该成员函数声明为static类型,去掉this指针;

我们将上述二个程序改变为:

include"windows.h"

include<process.h>

class ExampleTask 

 public: 

  void static taskmain(LPVOID param); 

  void StartTask(); 

}; 

void ExampleTask::taskmain(LPVOID param) 

{} 

void ExampleTask::StartTask() 

 _beginthread(taskmain,0,NULL);

 

int main(int argc, char* argv[])

{

 ExampleTask realTimeTask;

 realTimeTask.StartTask();

 return 0;

}

复制代码

include "windows.h"

include <process.h>

class ExampleTask 

 public: 

  void static taskmain(LPVOID param); 

}; 

 

void ExampleTask::taskmain(LPVOID param) 

{} 

 

int main(int argc, char* argv[])

{

 _beginthread(ExampleTask::taskmain,0,NULL);

 return 0;

}

复制代码

  均编译通过。

 

  将成员函数声明为静态虽然可以解决作为线程函数的问题,但是它带来了新的问题,那就是static成员函数只能访问static成员。解决此问题的一种途径是可以在调用类静态成员函数(线程函数)时将this指针作为参数传入,并在改线程函数中用强制类型转换将this转换成指向该类的指针,通过该指针访问非静态成员。

 

2)不定义类成员函数为线程函数,而将线程函数定义为类的友元函数。

这样,线程函数也可以有类成员函数同等的权限; 

  我们将程序修改为:

include windows.h"

include <process.h>

class ExampleTask 

 public: 

  friend void taskmain(LPVOID param); 

  void StartTask(); 

}; 

void taskmain(LPVOID param) 

 ExampleTask * pTaskMain = (ExampleTask *) param; 

 //通过pTaskMain指针引用 

void ExampleTask::StartTask() 

 _beginthread(taskmain,0,this);

}

 

int main(int argc, char* argv[])

{

 ExampleTask realTimeTask;

 realTimeTask.StartTask();

 return 0;

}

复制代码

 

 

3)可以对非静态成员函数实现回调,并访问非静态成员,此法涉及到一些高级技巧,在此不再详述。

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值