WEB开发网
开发学院软件开发VC MFC教程(9)-- MFC的进程和线程(1) 阅读

MFC教程(9)-- MFC的进程和线程(1)

 2010-03-25 20:35:08 来源:WEB开发网   
核心提示:CThreadLocal模板用来声明任意类型的线程私有的变量,因为通过模板可以自动的正确的转化(cast)指针类型,MFC教程(9)-- MFC的进程和线程(1)(11),程序员可以使用它来实现自己的线程局部变量,正如MFC实现线程局部的线程状态变量和模块-线程变量一样,这些对象要到第一次被访问时,才会被创建,CThr

CThreadLocal模板用来声明任意类型的线程私有的变量,因为通过模板可以自动的正确的转化(cast)指针类型。程序员可以使用它来实现自己的线程局部变量,正如MFC实现线程局部的线程状态变量和模块-线程变量一样。

CThrealLocal的成员函数CreateObject用来创建动态的指定类型的对象。成员函数GetData调用了基类CThreadLocalObject的同名函数,并且把CreateObject函数的地址作为参数传递给它。

另外,CThreadLocal模板重载了操作符号“*”、“->”,这样编译器将自动地进行有关类型转换,例如:

_AFX_THREAD_STATE *pStata = _afxThreadState

是可以被编译器接收的。

现在回头来看_afxThreadState的定义:

从以上分析可以知道,THREAD_LOCAL(class_name, ident_name)定义的结果并没有产生一个名为ident_name的class_name类的实例,而是产生一个CThreadLocal模板类(确切地说,是其派生类)的实例,m_nSlot初始化为0。所以,_afxThreadState实质上是一个CThreadLocal模板类的全局变量。每一个线程局部变量都对应了一个全局的CThreadLoacl模板类对象,模板对象的m_nSlot记录了线程局部变量对象的槽号。

进程模块状态afxBaseModuleState

进程模块状态定义如下:

PROCESS_LOCAL(_AFX_BASE_MODULE_STATE, _afxBaseModuleState)

表示它是一个_AFX_BASE_MODULE_STATE类型的进程局部(process local)的变量。

进程局部变量的实现方法主要是为了用于Win32s下。在Win32s下,一个DLL模块如果被多个应用程序调用,它将让这些程序共享它的全局数据。为了DLL的全局数据一个进程有一份独立的拷贝,MFC设计了进程私有的实现方法,实际上就是在进程的堆(Heap)中分配全局数据的内存空间。

在Win32下,DLL模块的数据和代码被映射到调用进程的虚拟空间,也就是说,DLL定义的全局变量是进程私有的;所以进程局部变量的实现并不为Win32所关心。但是,不是说afxBaseModuleState不重要,仅仅是采用PROCESS_LOCAL技术声明它是进程局部变量不是很必要了。PROCESS_LOCAL(class_name, ident_name)宏展开后如下:

AFX_DATADEF CProcessLocal<class_name> ident_name;

这里,CProcessLocal是一个类模板,从CProcessLocalObject类继承。

CProcessLocalObject和CProcessLocal的定义如下:

class CProcessLocalObject

{

public:

// Attributes

CNoTrackObject* GetData(CNoTrackObject* (AFXAPI*

pfnCreateObject)());

// Implementation

CNoTrackObject* volatile m_pObject;

~CProcessLocalObject();

};

template<class TYPE>

class CProcessLocal : public CProcessLocalObject

{

// Attributes

public:

inline TYPE* GetData()

{

TYPE* pData =(TYPE*)CProcessLocalObject::GetData(&CreateObject);

ASSERT(pData != NULL);

return pData;

}

inline TYPE* GetDataNA()

{ return (TYPE*)m_pObject; }

inline operator TYPE*()

{ return GetData(); }

inline TYPE* operator->()

{ return GetData(); }

// Implementation

public:

static CNoTrackObject* AFXAPI CreateObject()

{ return new TYPE; }

};

类似于线程局部对象,每一个进程局部变量都有一个对应的全局CProcessLocal模板对象。

状态对象的创建

状态对象的创建过程

回顾前一节的三个定义:

CThreadSlotData* _afxThreadData;

THREAD_LOCAL(_AFX_THREAD_STATE, _afxThreadState)

PROCESS_LOCAL(_AFX_BASE_MODULE_STATE, _afxBaseModuleState)

第一个仅仅定义了一个指针;第二和第三个定义了一个模板类的实例。相应的CThreadSlotData对象(全局)、_AFX_THREAD_STATE对象(线程局部)以及_AFX_BASE_MODULE_STATE对象(进程局部)并没有创建。当然,模块状态对象的成员模块-线程对象也没有被创建。这些对象要到第一次被访问时,才会被创建,这样做会提高加载DLL的速度。

上一页  6 7 8 9 10 11 

Tags:MFC 教程 MFC

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接