码迷,mamicode.com
首页 > 编程语言 > 详细

创建线程函数的方法

时间:2016-05-12 16:19:10      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:

1.线程函数

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

UINT ThreadFunction(LPVOID pParam)
{
 //线程处理代码
 return0;
}

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

while(1)
{
 WaitForSingleObject(…,…);//或WaitForMultipleObjects(…)
 //Do something
}

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

#include "windows.h"
#include 
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 
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 
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 
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 
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)可以对非静态成员函数实现回调,并访问非静态成员,此法涉及到一些高级技巧,在此不再详述。

创建线程函数的方法

标签:

原文地址:http://blog.csdn.net/wang15061955806/article/details/51362671

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!