MFC教程(9)-- MFC的进程和线程(1)
2010-03-25 20:35:08 来源:WEB开发网_afxThreadData仅仅定义为一个CThreadSlotData类型的指针,所指对象在第一次被引用时创建,在此之前该指针为空。下文_afxThreadData含义是它所指的对象。图9-5、9-6图解了MFC的线程局部存储机制的实现。
图9-5表示_afxTheadData使用TLS技术负责给进程分配一个TLS索引,然后使用TLS索引为进程的每一个线程分配线程局部存储空间。
图9-6表示每个线程的的局部存储空间可以分多个槽,每个槽可以放一个线程私有的数据指针。_afxThreadData负责给线程局部变量分配槽号并根据槽号存取数据。图的左半部分描述了管理槽的m_pSlotData及类CSlotData的结构,右半部分描述了管理MFC线程私有空间的m_list及类CThreadData的结构。
结合图9-6,对MFC线程局部存储机制总结如下:
每个线程局部变量(宏THREAD_LOCAL定义)占用一个槽,并有一个槽号。。
每个线程都有自己的MFC局部存储空间(下文多次使用“线程的MFC局部存储空间”,表示和此处相同的概念)。
通过TLS索引得到的是一个指针P1,它指向线程的MFC局部存储空间。
通过指针P1和线程局部变量在空间所占用的槽号,得到该槽所存储的线程私有的数据指针,即真正的线程私有数据的地址P2;
从地址P2得到数据D。
这个过程相当于几重间接寻址:先得到TLS线程私有数据指针,从TLS线程私有数据指针得到线程的MFC线程局部存储空间,再从MFC局部存储空间的对应槽得到一个线程私有的数据指针,从该指针得到最终的线程私有数据。如果没有这种机制,使用Win32 TLS只要一次间接寻址:得到TLS线程私有数据指针,从该指针得到最终的线程私有数据。
线程状态_afxThreadState
从上一节知道了MFC的线程局部存储机制。但有一点还不清楚,即某个线程局部变量所占用的槽号是怎么保存的呢?关于这点可从线程局部的线程状态变量_afxThreadState的实现来分析MFC的作法。变量_afxThreadState的定义如下:
THREAD_LOCAL(_AFX_THREAD_STATE, _afxThreadState)
THREAD_LOCAL 是一个宏,THREAD_LOCAL(class_name, ident_name)宏展开后如下:
AFX_DATADEF CThreadLocal<class_name> ident_name;
这里,CThreadLocal是一个类模板,从CThreadLocalObject类继承。
CThreadLocalObject和CThreadLocal的定义如下:
class CThreadLocalObject
{
public:
// Attributes
CNoTrackObject* GetData(CNoTrackObject* (AFXAPI*
pfnCreateObject)());
CNoTrackObject* GetDataNA();
// Implementation
int m_nSlot;
~CThreadLocalObject();
};
更多精彩
赞助商链接