1.CWinApp是CWinThread的一个继承实例,我们继承CWinThread时可以参考CWinApp的工作方法;
2.CWinThread继承类对象在调用AfxBeginThread或CWinThread::CreateThread()后线程立即启动,这两种方法都可以创建界面UI线程或工作者线程。
3.WM_QUIT消息可以被任何线程处理。或使用PostQuitMessage发送WM_QUIT给消息队列。注意,WM_QUIT永远不会到达窗口过程,因为GetMessage得到WM_QUIT后就会返回FALSE,从而结束消息循环,最后进程结束,程序退出。不论在线程内部还是外部,都可以向线程发送WM_QUIT来结束线程。
4.一个线程向另外一个线程发送消息是通过操作系统实现的。利用Windows操作系统的消息驱动机制,当一个线程发出一条消息时,操作系统首先接收到该消息,然后把该消息转发给目标线程,接收消息的线程必须已经建立了消息循环。
线程的退出有多种方式,比如可以调用TerminateThread()函数强制线程退出,但不推荐这种方式,因为这样做会导致线程中的资源来不及释放。最好的也是推荐的方式,是让线程函数自己退出。就像上面介绍的SetProgress()函数中,用全局变量g_exitThread使线程退出。
而AnalyseProc用WAIT_OBJECT_0 ==WaitForSingleObject(m_eventExitAnalyse.m_hThread,0)这种方式来退出线程,还有在SetSlider函数中利用发送自定义消息WM_QUIT_THREAD的方式令线程退出。这些都是可以使用的方法。
当主线程要退出时,为了能保证线程的资源能全部地释放,主线程必须等待工作线程退出。线程对象和进程对象一样,也是内核对象,而且线程对象的特点是当线程退出时,线程内核对象会自动变为有信号状态,能够唤醒所有正在等待它的线程。我们通常都习惯于使用WaitForSingleObject等函数来等待某个内核对象变为有信号状态,但是我想说的是,在主线程中不要使用WaitForSingleObject和WaitForMultipleObjects两个函数等待线程退出,其原因就是有导致程序死锁的隐患,特别是线程函数里调用了SendMessage或是直接操作了MFC对象,更易出现此种现象。下面的函数是一个在主线程中用来等待SetProgress()线程函数退出的函数:
//退出线程
void CThreadTest::OnButton2()
{
g_exitThread=TRUE; //设置全局变量为真,令线程退出
#if 1
WaitForSingleObject(m_pThread1->m_hThread,INFINITE); //无限等待
#else
DWORD dRet;
MSG msg;
while (1)
{
dRet=::MsgWaitForMultipleObjects(1,&m_pThread1->m_hThread,FALSE,INFINITE,QS_ALLINPUT);
if (dRet == WAIT_OBJECT_0+1)
{
while (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else