ATL学习笔记(1):ATL单线程与多线程套间对象引用计数的基础实现
2014-06-04 11:35
393 查看
COM对象必须在套间中运行。套间分为单线程套间和多线程套间。在单线程套间中,套间保证COM对象实例仅有一个线程可以访问,而在多线程套间中,COM对象实例可同时被多个线程访问。因此,在多线程套间中执行的COM对象必须解决多线程访问的同步和冲突等线程安全相关问题。
引用计数器管理的实现——CComObjectRootEx
ATL使用CComObjectRootEx类来实现对COM对象计数器的管理,因此,所有的基于ATL的COM对象必须从该类继承。CComObjectRootEx类的声明和实现如下(精简):
template< class ThreadModel >
class CComObjectRootEx : public CComObjectRootBase
{
public:
typedef ThreadModel _ThreadModel;
...
ULONG InternalAddRef()
{ return _ThreadModel::Increment(&m_dwRef); } // 引用计数器m_dwRef在
// CComObjectRootBase中声明
ULONG InternalRelease()
{ return _ThreadModel::Decrement(&m_dwRef); }
};
由上述代码可见,对于CComObjectRootEx类:
1) 实现了对引用计数器递增与递减的操作,但并未实现IUnknown接口所要求的对对象声明周期的管理,没有在计数器归零后释放对象。
2) 对于应用技术的操作依赖于模板参数ThreadModel,即该对象的线程模型,包括CComSingleThreadModel类和CComMultiThreadModel类。因此,对象访问的线程安全问题,将在这两个类中实现。
套间线程模型的实现——CComSingleThreadModel与CComMultiThreadModel
CComSingleThreadModel类和CComMultiThreadModel类的实现概要如下:
class CComSingleThreadModel
{
typedef CComFakeCriticalSection AutoCritcalSection;
typedef CComFakeCriticalSection CriticalSection;
typedef CComSingleThreadMode ThreadModeNoCS;
static ULONG Increment(LPLONG p) { return ++(*p); }
static ULONG Decrement(LPLONG p) { return --(*p); }
};
class CComMultiThreadModel
{
typedef CComAutoCriticalSection AutoCritcalSection;
typedef CComCriticalSection CriticalSection;
typedef CComMultiThreadModeNoCs ThreadModeNoCS;
static ULONG Increment(LPLONG p)
{ return InterlockedIncrement(p); }
static ULONG Decrement(LPLONG p)
{ return InterlockedDecrement(p); }
};
CComSingleThreadModel与CComMultiThreadModel具有相同的结构和方法声明,只是在实现计数器递增或递减的时候,CComMultiThreadModel采用了线程安全的API函数而CComSingleThreadModel。并且,CComMultiThreadModel声明了真实的临界区对象类型(CComAutoCriticalSection和CComCriticalSection ),供其他需要线程同步的操作使用。CComSingleThreadModel仅仅为保持与CComMultiThreadModel具有相同的结构而声明了两个伪装的临界区类型(CComFakeCriticalSection)。CComFakeCriticalSection是伪装的临界区类,其中并没有提供真实的临界区,而仅仅声明了与CComAutoCriticalSection和CComCriticalSection相同的方法。
结论
为了对单线程套间对象与多线程套间对象的引用计数实现一个统一的访问控制模型,ATL将COM的引用计数器管理的实现从IUnknown接口所定义的对象生命周期管理中抽出,并在CComObjectRootEx类中单独实现。CComObjectRootEx通过模板参数指定对象所使用的线程模型。在CComMultiThreadModel中声明和实现了线程安全的方法。由此,任何ATL COM对象必须继承自CComObjectRootEx来实现引用计数,并在继承时指定线程模型。
引用计数器管理的实现——CComObjectRootEx
ATL使用CComObjectRootEx类来实现对COM对象计数器的管理,因此,所有的基于ATL的COM对象必须从该类继承。CComObjectRootEx类的声明和实现如下(精简):
template< class ThreadModel >
class CComObjectRootEx : public CComObjectRootBase
{
public:
typedef ThreadModel _ThreadModel;
...
ULONG InternalAddRef()
{ return _ThreadModel::Increment(&m_dwRef); } // 引用计数器m_dwRef在
// CComObjectRootBase中声明
ULONG InternalRelease()
{ return _ThreadModel::Decrement(&m_dwRef); }
};
由上述代码可见,对于CComObjectRootEx类:
1) 实现了对引用计数器递增与递减的操作,但并未实现IUnknown接口所要求的对对象声明周期的管理,没有在计数器归零后释放对象。
2) 对于应用技术的操作依赖于模板参数ThreadModel,即该对象的线程模型,包括CComSingleThreadModel类和CComMultiThreadModel类。因此,对象访问的线程安全问题,将在这两个类中实现。
套间线程模型的实现——CComSingleThreadModel与CComMultiThreadModel
CComSingleThreadModel类和CComMultiThreadModel类的实现概要如下:
class CComSingleThreadModel
{
typedef CComFakeCriticalSection AutoCritcalSection;
typedef CComFakeCriticalSection CriticalSection;
typedef CComSingleThreadMode ThreadModeNoCS;
static ULONG Increment(LPLONG p) { return ++(*p); }
static ULONG Decrement(LPLONG p) { return --(*p); }
};
class CComMultiThreadModel
{
typedef CComAutoCriticalSection AutoCritcalSection;
typedef CComCriticalSection CriticalSection;
typedef CComMultiThreadModeNoCs ThreadModeNoCS;
static ULONG Increment(LPLONG p)
{ return InterlockedIncrement(p); }
static ULONG Decrement(LPLONG p)
{ return InterlockedDecrement(p); }
};
CComSingleThreadModel与CComMultiThreadModel具有相同的结构和方法声明,只是在实现计数器递增或递减的时候,CComMultiThreadModel采用了线程安全的API函数而CComSingleThreadModel。并且,CComMultiThreadModel声明了真实的临界区对象类型(CComAutoCriticalSection和CComCriticalSection ),供其他需要线程同步的操作使用。CComSingleThreadModel仅仅为保持与CComMultiThreadModel具有相同的结构而声明了两个伪装的临界区类型(CComFakeCriticalSection)。CComFakeCriticalSection是伪装的临界区类,其中并没有提供真实的临界区,而仅仅声明了与CComAutoCriticalSection和CComCriticalSection相同的方法。
结论
为了对单线程套间对象与多线程套间对象的引用计数实现一个统一的访问控制模型,ATL将COM的引用计数器管理的实现从IUnknown接口所定义的对象生命周期管理中抽出,并在CComObjectRootEx类中单独实现。CComObjectRootEx通过模板参数指定对象所使用的线程模型。在CComMultiThreadModel中声明和实现了线程安全的方法。由此,任何ATL COM对象必须继承自CComObjectRootEx来实现引用计数,并在继承时指定线程模型。
相关文章推荐
- ATL学习笔记(1):ATL单线程与多线程套间对象引用计数的基础实现
- 类对象引用计数使用模板实现(奇特的递归模板模式)
- Java虚拟机垃圾回收(一) 基础:回收哪些内存/对象 引用计数算法 可达性分析算法 finalize()方法 HotSpot实现分析
- C++简单实现对象引用计数示例
- ATL学习笔记(2): ATL对象多线程访问临界锁的实现
- 如何实现引用计数对象
- Java虚拟机垃圾回收(一) 基础:回收哪些内存/对象 引用计数算法 可达性分析算法 finalize()方法 HotSpot实现分析
- ATL是如何实现线程安全的引用计数和多线程控制的
- C++简单实现对象引用计数示例(转)
- 垃圾回收机制中,引入计数是如何实现的,内部原理是什么,怎么维持对象引用的
- c++的对象计数问题的多线程实现
- ATL学习笔记(2): ATL对象多线程访问临界锁的实现
- com学习笔记(3)基本的com接口-引用计数的实现
- TAO教程之四:改进服务端之通过POA策略实现持久化的对象引用
- CORBA技术系列二:CORBA基础概念-对象引用
- 引用计数与对象生存期管理
- Javascript乱弹设计模式系列(0) - 面向对象基础以及接口和继承类的实现
- 《面向对象基础:C++实现》学习笔记之七
- linux-2.6内核模块引用计数的实现
- 实现思想list hashmap性能差别及对象引用之一