最近几天在读windows核心编程,对于学海无涯的道理深有体会。越读越发现自己学习的不够。在读线程相关章节的时候感到windows的API实在是复杂,CreateThread函数就拥有六个参数。 每个参数都有几个可设定的值。这种情况就给使用和记忆带来一定的困难。接触过java的人都知道java中有Thread类和Runnable接口,可以方便的创建线程。将线程看作一个对象来处理将使问题简化。我模仿java的结构创建了一个简单的Thread类, 具体实现如下:
#ifndef _WTHREAD_H_
#define _WTHREAD_H_
#include <exception>
class wRunnable
{
public:
virtual void Run() = 0;
};
class wThread
{
public:
wThread(IN wRunnable* pRunnable = NULL,
IN LPSECURITY_ATTRIBUTES lpThreadAttributes = NULL,
IN SIZE_T dwStackSize = 0,
IN DWORD dwCreationFlags = 0);
~wThread();
void Start() throw(std::exception);
DWORD GetThreadId() const;
HANDLE GetThreadHandle() const;
static DWORD WINAPI ThreadProc(PVOID);
protected:
virtual void Run() {}
private:
LPSECURITY_ATTRIBUTES m_lpThreadAttributes;
HANDLE m_hThread;
DWORD m_dwThreadId;
SIZE_T m_dwStackSize;
DWORD m_dwCreateFlags;
wRunnable *m_pRunnable;
};
#endif // _WTHREAD_H_
#include "stdafx.h"
#include "wThread.h"
DWORD WINAPI wThread::ThreadProc(PVOID parm)
{
wThread* pThread = (wThread*) parm;
if(pThread->m_pRunnable) {
pThread->m_pRunnable->Run();
goto END_LINE;
}
pThread->Run();
END_LINE:
pThread->m_hThread = NULL;
pThread->m_dwThreadId = 0;
return 0;
}
wThread::wThread(IN wRunnable* pRunnable,
IN LPSECURITY_ATTRIBUTES lpThreadAttributes,
IN SIZE_T dwStackSize,
IN DWORD dwCreationFlags)
: m_pRunnable(pRunnable)
, m_lpThreadAttributes(lpThreadAttributes)
, m_dwStackSize(dwStackSize)
, m_dwCreateFlags(dwCreationFlags)
, m_hThread(NULL)
, m_dwThreadId(0)
{
}
wThread::~wThread()
{
if(m_pRunnable) delete m_pRunnable;
}
void wThread::Start() throw(std::exception)
{
if(m_hThread != NULL) {
throw std::exception("Can't execute create more than once !");
}
m_hThread = CreateThread(m_lpThreadAttributes,
m_dwStackSize,
ThreadProc, this,
m_dwCreateFlags,
&m_dwThreadId);
if(m_hThread == INVALID_HANDLE_VALUE
|| m_hThread == NULL) {
throw std::exception("Create a thread failed");
}
}
HANDLE wThread::GetThreadHandle() const
{
return m_hThread;
}
DWORD wThread::GetThreadId() const
{
return m_dwThreadId;
}
代码中关键的部分是:
DWORD WINAPI wThread::ThreadProc(PVOID parm)
{
wThread* pThread = (wThread*) parm;
if(pThread->m_pRunnable) {
pThread->m_pRunnable->Run();
goto END_LINE;
}
pThread->Run();
END_LINE:
pThread->m_hThread = NULL;
pThread->m_dwThreadId = 0;
return 0;
}
这个函数是wThread类的静态函数,它将wThread的对象作为参数进行传递,进而可以对wThread的Run函数进行调用或者调用wRunnable的Run函数。
测试代码如下:
#define MESSAGE_BOX(x) MessageBox(NULL, x, "message", 0)
class MyThread : public wThread
{
protected:
virtual void Run()
{
MESSAGE_BOX("In MyThread");
}
};
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
try {
wThread* pThread = new MyThread;
pThread->Start();
WaitForSingleObject(pThread->GetThreadHandle(), INFINITE);
TCHAR chMessage[255];
sprintf(chMessage, "%d", pThread->GetThreadHandle());
MESSAGE_BOX(chMessage);
delete pThread;
} catch(std::exception& e) {
MESSAGE_BOX(e.what());
}
return 0;
}
#ifndef _WTHREAD_H_
#define _WTHREAD_H_
#include <exception>
class wRunnable
{
public:
virtual void Run() = 0;
};
class wThread
{
public:
wThread(IN wRunnable* pRunnable = NULL,
IN LPSECURITY_ATTRIBUTES lpThreadAttributes = NULL,
IN SIZE_T dwStackSize = 0,
IN DWORD dwCreationFlags = 0);
~wThread();
void Start() throw(std::exception);
DWORD GetThreadId() const;
HANDLE GetThreadHandle() const;
static DWORD WINAPI ThreadProc(PVOID);
protected:
virtual void Run() {}
private:
LPSECURITY_ATTRIBUTES m_lpThreadAttributes;
HANDLE m_hThread;
DWORD m_dwThreadId;
SIZE_T m_dwStackSize;
DWORD m_dwCreateFlags;
wRunnable *m_pRunnable;
};
#endif // _WTHREAD_H_
#include "stdafx.h"
#include "wThread.h"
DWORD WINAPI wThread::ThreadProc(PVOID parm)
{
wThread* pThread = (wThread*) parm;
if(pThread->m_pRunnable) {
pThread->m_pRunnable->Run();
goto END_LINE;
}
pThread->Run();
END_LINE:
pThread->m_hThread = NULL;
pThread->m_dwThreadId = 0;
return 0;
}
wThread::wThread(IN wRunnable* pRunnable,
IN LPSECURITY_ATTRIBUTES lpThreadAttributes,
IN SIZE_T dwStackSize,
IN DWORD dwCreationFlags)
: m_pRunnable(pRunnable)
, m_lpThreadAttributes(lpThreadAttributes)
, m_dwStackSize(dwStackSize)
, m_dwCreateFlags(dwCreationFlags)
, m_hThread(NULL)
, m_dwThreadId(0)
{
}
wThread::~wThread()
{
if(m_pRunnable) delete m_pRunnable;
}
void wThread::Start() throw(std::exception)
{
if(m_hThread != NULL) {
throw std::exception("Can't execute create more than once !");
}
m_hThread = CreateThread(m_lpThreadAttributes,
m_dwStackSize,
ThreadProc, this,
m_dwCreateFlags,
&m_dwThreadId);
if(m_hThread == INVALID_HANDLE_VALUE
|| m_hThread == NULL) {
throw std::exception("Create a thread failed");
}
}
HANDLE wThread::GetThreadHandle() const
{
return m_hThread;
}
DWORD wThread::GetThreadId() const
{
return m_dwThreadId;
}
代码中关键的部分是:
DWORD WINAPI wThread::ThreadProc(PVOID parm)
{
wThread* pThread = (wThread*) parm;
if(pThread->m_pRunnable) {
pThread->m_pRunnable->Run();
goto END_LINE;
}
pThread->Run();
END_LINE:
pThread->m_hThread = NULL;
pThread->m_dwThreadId = 0;
return 0;
}
这个函数是wThread类的静态函数,它将wThread的对象作为参数进行传递,进而可以对wThread的Run函数进行调用或者调用wRunnable的Run函数。
测试代码如下:
#define MESSAGE_BOX(x) MessageBox(NULL, x, "message", 0)
class MyThread : public wThread
{
protected:
virtual void Run()
{
MESSAGE_BOX("In MyThread");
}
};
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
try {
wThread* pThread = new MyThread;
pThread->Start();
WaitForSingleObject(pThread->GetThreadHandle(), INFINITE);
TCHAR chMessage[255];
sprintf(chMessage, "%d", pThread->GetThreadHandle());
MESSAGE_BOX(chMessage);
delete pThread;
} catch(std::exception& e) {
MESSAGE_BOX(e.what());
}
return 0;
}