在类中使用线程,必须要注意两点
一、线程函数必须是类的静态成员函数或全局函数,建议最好声明为类的静态成员函数。原因:线程处理函数有且只有一个void*类型的参数。类的非静态成员函数被调用时,系统会隐式传入一个参数——this指针,如果把线程处理函数定义为类的一般成员函数,该线程处理函数就有两个参数了,一个是线程创建时的参数,另一个是被调用时隐式传入的this指针。利用反证法,所以要把线程处理函数定义为静态成员函数或全局函数。
二、线程的参数最好传该对象的指针,也就是this指针,而且要注意做相应类型转换,这样就可以通过this指针来访问类的所有数据成员和成员函数了。
示例代码如下:
// ThreadInClass.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
#include <deque>
//Test.h
//2012.10.10 by l0g1n
#pragma once
#include <stdio.h>
#include <Windows.h>
#include <stdlib.h>
#include <iostream>
#include <string>
using namespace std;
int g_account = 0;
std::deque<DWORD> connQueue;
class CTest
{
public:
CTest(void);
//void ThreadCall();
~CTest(void);
private:
void ThreadCall();
public:
static void TestProc(PVOID lParam);
private:
HANDLE m_hThread;
int i;
public:
HANDLE m_hEvent;
};
//Test.cpp
//2012.10.10 by l0g1n
//#include "Test.h"
void CTest::TestProc(PVOID lParam)
{
cout<<"已进入线程函数"<<endl;
CTest *p=(CTest*)lParam;
while(1)
{
DWORD dwResult=WaitForSingleObject(p->m_hEvent,100);
if(dwResult==WAIT_TIMEOUT)
{
for(std::deque<DWORD>::iterator it = connQueue.begin(); it != connQueue.end(); it++)
cout << *it << '\t';
p->i = g_account;
p->ThreadCall();
}
else
break;
}
}
CTest::CTest(void)
{
for(int ii = 0; ii < 10; ii++)
connQueue.push_back(ii);
cout<<"已进入类中构造函数"<<endl;
i=1;
m_hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
m_hThread=CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)&TestProc,(LPVOID)this,0,NULL);//传递进去this指针,用于调用类中函数
CloseHandle(m_hThread);
}
void CTest::ThreadCall()
{
cout<<"线程函数调用类中函数成功 "<<i++<<" 输入q退出!"<<endl;
Sleep(1000);
}
CTest::~CTest(void)
{
cout<<"已进入类中析构函数"<<endl;
}
//main.cpp
//2012.10.10 by l0g1n
//#include "Test.h"
int main()
{
CTest test;
string str;
do
{
cin>>str;
}while(str!="q");
SetEvent(test.m_hEvent);
system("pause");
return 0;
}