函数原型:
CWinThread* AfxBeginThread( AFX_THREADPROC pfnThreadProc, LPVOIDpParam, intnPriority= THREAD_PRIORITY_NORMAL, UINTnStackSize= 0, DWORDdwCreateFlags= 0, LPSECURITY_ATTRIBUTESlpSecurityAttrs= NULL );
CWinThread* AfxBeginThread( CRuntimeClass* pThreadClass, intnPriority= THREAD_PRIORITY_NORMAL, UINTnStackSize= 0, DWORDdwCreateFlags= 0, LPSECURITY_ATTRIBUTESlpSecurityAttrs= NULL );
以上两个函数分别为工作者线程和用户界面线程的原型。
MFC中有两类线程,即上边的工作者线程和用户界面线程。两者的区别主要在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环。
工作者线程没有消息机制,用来执行后台计算和维护任务,如冗长的计算过程,打印机的后台打印等。
用户界面线程一般用于处理独立于其他线程之外的用户输入,响应用户及系统产生的事件和消息等。
但是对于win32的API编程来说,这两种线程是没有区别的,她们都只需要线程的启动地址即可。
下面分别介绍这两个函数原型及参数:
工作者线程:
CWinThread* AfxBeginThread( AFX_THREADPROC pfnThreadProc, LPVOID pParam, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORDdwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );
参数:pfnThreadProc:指向工作者线程的执行函数的指针,工作者线程函数原型必须声明如下:
UINT MyControllingFunction( LPVOID pParam );
pParam:传给线程函数的一个参数,如上工作线程函数原型中的pParam。
nPriority:线程的优先级,如果为0,子线程和创建线程有着同等的优先级。可以通过SetThreadPriority函数设置指定线程的优先级。
nStackSize:指定新线程栈的大小,如果为0,子线程堆栈的大小和父进程一致。
dwCreateFlags:指定创建的工作线程的额外标志。可以是其中之一:
- CREATE_SUSPEND 线程创建后立即挂起,直到调用ResumeThread函数
- 0 创建完线程后,线程立即执行。
RUNTIME_CLASS( class_name )。class_name 为类的实际名称。
其他和工作线程函数一致。
对此函数说明:
//线程对象的指针
CWinThread *m_pAlarmThread ;
//Windows下线程同步的基本方法有3种:互斥对象、事件对象、关键代码段(临界区)
//临界区 线程加锁 CCriticalSection是对临界区的封装类
CCriticalSection m_cs;
//开启线程
m_pAlarmThread = AfxBeginThread(AlarmThread,this);
//线程函数
static UINT AlarmThread(LPVOID param); //报警线程
void Alarm(); //与上面线程函数一起使用
//线程函数具体实现
UINT CDigitalScanCollectView::AlarmThread(LPVOID param)
{
CDigitalScanCollectView* pThis = (CDigitalScanCollectView*)param;
pThis->Alarm();
return 0;
}
void CDigitalScanCollectView::Alarm()
{
while(TRUE)
{
WaitForSingleObject(m_AlarmEvent,INFINITE);
if (m_bIsAlarmThreadQuit)
{
break;
}
//线程处理逻辑代码处
m_cs.Lock(); //加锁
m_cs.Unlock(); //解锁
m_AlarmEvent.ResetEvent();
}
}
//退出线程代码逻辑
m_bIsAlarmThreadQuit = true;
SetEvent(m_AlarmEvent);
if(WAIT_TIMEOUT == WaitForSingleObject(m_pAlarmThread->m_hThread,2000))
{
DWORD dwExitCode;
if(::GetExitCodeThread(m_pAlarmThread->m_hThread,&dwExitCode))
{
::TerminateThread(m_pAlarmThread->m_hThread,dwExitCode);
}
CloseHandle(m_pAlarmThread);
}