Chinaunix首页 | 论坛 | 博客
  • 博客访问: 14517820
  • 博文数量: 5645
  • 博客积分: 9880
  • 博客等级: 中将
  • 技术积分: 68081
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-28 13:35
文章分类

全部博文(5645)

文章存档

2008年(5645)

我的朋友

分类:

2008-04-28 21:01:06

下载本文示例代码
  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 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)可以对非静态成员函数实现回调,并访问非静态成员,此法涉及到一些高级技巧,在此不再详述。共3页。 1 2 3 :   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 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)可以对非静态成员函数实现回调,并访问非静态成员,此法涉及到一些高级技巧,在此不再详述。共3页。 1 2 3 : 下载本文示例代码


深入浅出Win32多线程程序设计之线程控制深入浅出Win32多线程程序设计之线程控制深入浅出Win32多线程程序设计之线程控制深入浅出Win32多线程程序设计之线程控制深入浅出Win32多线程程序设计之线程控制深入浅出Win32多线程程序设计之线程控制深入浅出Win32多线程程序设计之线程控制深入浅出Win32多线程程序设计之线程控制深入浅出Win32多线程程序设计之线程控制深入浅出Win32多线程程序设计之线程控制深入浅出Win32多线程程序设计之线程控制深入浅出Win32多线程程序设计之线程控制深入浅出Win32多线程程序设计之线程控制深入浅出Win32多线程程序设计之线程控制深入浅出Win32多线程程序设计之线程控制
阅读(132) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~