在windows下创建一个线程有多个创建函数可以调用,不过和操作系统距离最近的应该是一个
叫做 CreateThread 的API 函数。不过,使用这个接口创建出来的线程是不安全的,使用的时候
要在外面wait 它结束。比如:
...
thread1 = CreateThread(...);
::WaitForSingleObject(thread1, time);//这一句必须要有,否则可能这个线程还没结束,主线程就跑完了
...
我们可以封装一个类,使用更方便
定义一个CThread类,头文件WinThread.h如下:
#ifndef __WINTHREAD_H__
#define __WINTHREAD_H__
#include <Windows.h>
class CThread
{
CThread(const CThread&);
CThread& operator=(const CThread&);
public:
CThread();
~CThread();
bool Start();
bool IsRunning()const;
HANDLE handle()const;
DWORD threadID()const;
void SetWaitTime(DWORD dwMilliseconds, bool bTimeImmediately = false);
protected:
DWORD WaitForComplete(DWORD dwMilliseconds = INFINITE);
void DoWork();
private:
static DWORD WINAPI ThreadProc(LPVOID lpParameter);
HANDLE m_hThread; ///< Thread handle
DWORD m_dwThreadID;///< Thread ID
DWORD m_dwMilliseconds;//< Wait time
bool m_bTimeImmediately;//< whether time immediately from set wait time
};
#endif
类的实现文件WinThread.cpp:
#include "./WinThread.h"
#include <iostream>
CThread::CThread()
:m_hThread(NULL),
m_bTimeImmediately(false),
m_dwMilliseconds(INFINITE)
{
}
CThread::~CThread()
{
if(!m_bTimeImmediately)
{
WaitForComplete(m_dwMilliseconds);
}
if(m_hThread)
{
::CloseHandle(m_hThread);
m_hThread = NULL;
}
}
bool CThread::Start()
{
if(IsRunning())
{
return true;
}
if(m_hThread)
{
::CloseHandle(m_hThread);
m_hThread = NULL;
}
m_hThread = ::CreateThread(NULL, 0, ThreadProc, this, 0, &m_dwThreadID);
return m_hThread != NULL;
}
bool CThread::IsRunning()const
{
return m_hThread != NULL;
}
HANDLE CThread::handle()const
{
return m_hThread;
}
void CThread::SetWaitTime(DWORD dwMilliseconds, bool bTimeImmediately/* = false */)
{
m_dwMilliseconds = dwMilliseconds;
m_bTimeImmediately = bTimeImmediately;
if(m_bTimeImmediately)
{
WaitForComplete(dwMilliseconds);
}
}
DWORD CThread::WaitForComplete(DWORD dwMilliseconds /* = INFINITE */)
{
return ::WaitForSingleObject(m_hThread, dwMilliseconds);
}
void CThread::DoWork()
{
//do anything you want
for(int i = 0; i < 50; ++i)
{
std::cout<<"created a new thread . ID = "<<m_dwThreadID<<std::endl;
}
}
DWORD WINAPI CThread::ThreadProc(LPVOID lpParameter)
{
CThread* pThread = reinterpret_cast<CThread*>(lpParameter);
if(pThread)
{
pThread->DoWork();
}
return 0;
}
在使用这个类的时候,如果你不记着要结束这个线程,那么它自动会等到所有事情做完才会结束(这个线程对象
生命周期结束时系统调用它的析构函数,WaitForComplete的时间是INFINITE);
如果你要设置一个结束时间,那么你可以调用SetWaitTime 函数去设置这个时间,这个时候你要关注一个变量:
bool bTimeImmediately
这个变量的意义是:如果设置为 true,则标识要从设置这个等待时间开始计时,到时间就结束线程;否则,这个时
间是从这个线程析构时开始计时。
写个测试函数:
void TestThread()
{
CThread thread;
thread.Start();
thread.SetWaitTime(3, true);
}
void main()
{
TestThread();
}
运行结果:
created a new thread . ID = 3932
created a new thread . ID = 3932
created a new thread . ID = 3932
created 请按任意键继续. . .
没有打印出完整的50句就结束了。
下面我们尝试另一个测试例子:
void TestThread()
{
CThread thread;
thread.Start();
thread.SetWaitTime(3, false );
}
void main()
{
TestThread();
}
运行结果:
created a new thread . ID = 3032
created a new thread . ID = 3032
created a new thread . ID = 3032
created a new thread . ID = 3032
created a new thread . ID = 3032
created a new thread . ID = 3032
created a new thread . ID = 3032
created a new thread . ID = 3032
created a new thread . ID = 3032
creat 请按任意键继续. . .
这个也没有打印出完整的 50 行,但是比上一个测试用例打印的行数要多,是因为它的计时是在子线程
对象析构的时候才开始的。