`

COM多线程原理与应用

    博客分类:
  • COM
阅读更多

COM多线程原理与应用

目录:

COM多线程原理与应用

目录:

前言:

套间:

套间的定义:

套间的分类:

套间的进入和退出:

对象的同步:

组件对象的同步:

COM对象线程模型:

进程内对象线程模型的种类:

ATL对多线程的支持:

对象引用的保护:

成员变量的保护:

COM+导致的变化:

上下文概述:

上下文对象:

调用对象:

 

前言:

COM多线程一直是个不容易弄清的问题,我也被困扰了很久,特别是COM在线程方面的术语总是不能统一。本文是为了将我所学所用得做一个总结,本文不保证一定正确,但是会随着时间的推移逐渐完善改正。

 

套间:

套间的定义:

       我个人认为<<COM技术内幕>>中关于套间的定义是错误的,应采用<<COM本质论>>中的定义。

<<COM技术内幕>>-----

套间(Apartment),一个由用户界面线程(套间线程)和一个消息循环构成的概念性实体。

<<COM本质论>>------

套间定义了一组对象的逻辑组合,这些对象共享同一组并发性和重入限制。一个线程要想使用COM,必须先进入一个套间。COM规定,只有运行在对象套间中的线程才能访问该对象。

套间的分类:

COM定义了两种类型的套间,STA(单线程套间)和MTA(多线程套间)。

STA的特点是套间内永远只有一个线程运行,并且一定是创建该套间的初始线程。因而开发只运行在STA中的组件不需要考虑线程同步等问题。

STA中包含了一个不可见的窗口,所以透过窗口的消息循环机制对消息队列的处理,保证了同一时刻只有一个调用请求被执行,这就是组件不需要处理同步的原因。

 

MTA的特点是套间内可以有多个线程运行,并且还可以创建新的线程。在MTA中运行的组件必须自己实现线程的同步。

 

 

套间的进入和退出:

线程通过CoInitializeEx函数进入套间,该函数的第二个参数通过传递COINIT_APARTMENTTHREADEDCOINIT_MULTITHREADED标志了套间类型。如果传递COINIT_APARTMENTTHREADED,该线程将创建自己私有的套间,别人不能进入。如果传递COINIT_MULTITHREADED,该线程将进入当前进程范围内的MTA

线程调用CoUninitialize函数用于退出所在的套间。只有退出后才可以进入其它类型的套间。

 

对象的同步:

组件对象的同步:

根据是否支持多线程同步,组件对象可以分为单线程对象和多线程对象。

COM对象线程模型:

每个COM对象都可以决定自己将运行在什么样的套间内,这称为COM对象的线程模型。

组件将运行在什么样的套间里面,这是由组件开发者决定的,调用组件的客户程序不需要关心。但是如果调用线程所在的套间和组件运行的套间不是同一套间,COM将插入代理/存根机制,调用线程在自身的套间内调用代理上的方法使用对象方法,而对象将运行在它需要的套间内。

进程内对象线程模型的种类:

线程模型的种类取决于注册表中ThreadingModel的值----------

1  Both 表示组件可以运行在STAMTA

2  Free 表示组件只能运行在MTA

3  Apartment表示组件只能运行在STA

4  为空表示组件只能运行在进程第一个创建的STA(主STA中)中。

如果调用线程的套间能够满足进程内组件的线程模型的要求,则直接创建组件对象,并不需要代理。

如果调用线程的套间不能满足进程内组件的线程模型的要求,则COM会在另一个合适的套间内(如果没有合适的套间,COM会创建一个)创建对象,然后给调用线程返回代理。

如果组件和客户程序不在同一个进程或者不在同一台机器,那必然是在两个套间中,COM会创建代理/存根。

如果组件对象的线程模型是Both或者Free,组件必须是多线程对象。

如果组件对象的线程模型是空,则组件可以是单线程对象或者多线程对象。这时候多线程对象内部的同步机制其实没有意义,因为不会有多个线程同时访问对象。

如果组件对象的线程模型是Apartment,情况将分两种:

a)       组件内部没有全局变量和静态变量,组件可以是单线程对象

b)      组件内部有全局变量和静态变量,组件应该是多线程对象,并对全局变量和静态变量进

行访问保护。

 

ATL对多线程的支持:

ATL中对COM对象中同步的支持有自己的考虑:如果COM对象本身就是不考虑同步的单线程对象,ATL就不应该对该对象的任何数据成员包括对象引用变量m_cRef进行同步保护。因为同步保护是需要额外的耗费资源的。ATL中的原则是只在应该需要保护的场合进行同步保护。这样做是符合ATL的设计目的----一切为了效率。

对象引用的保护:

CComSingleThreadModelCComMultiThreadModelCComMultiThreadModelNoCS类里面都定义了静态成员函数IncrementDecrementCComObjectRootEx类的模板参数接受以上三个类并使用他们的静态成员函数,而我们的组件实现类从CComObjectRootEx类派生,从而获得了根据我们组件是否支持多线程而对对象引用进行同步的功能。一句话,我们只要派生具有合适的模板参数的CComObjectRootEx类就可以了。如下面我们的类:

class ATL_NO_VTABLE CMIS :

     public CComObjectRootEx<CComSingleThreadModel>,

CMIS类不需要考虑对象引用的同步保护,因为我们的组件对象是单线程对象,线程模型为空或者为Apartment

       但是请注意ATL工程的组件类脚本中默认线程模型是both,这就会带来问题,所以我们手动修改它。

       如果我们改动代码如下:

class ATL_NO_VTABLE CMIS :

     public CComObjectRootEx< CComMultiThreadModel >,那么我们的组件对象引用计数就受到同步保护,而且我们的组件对象自己负责同步保护。这样如果CMIS类里有成员变量,那么我们要对成员变量进行同步保护。

成员变量的保护:

       采用临界区方式进行同步保护我们要利用类CComMultiThreadModel。我们的组件实现类派生自CComObjectRootEx< CComMultiThreadModel >类。使用的方法极其简单,我们只要在需要防止多个线程同时执行的函数内部开始处加上如下代码:

       ObjectLock Lock(this);

     如果想使用多个临界区的话使用方法就没这么简单了,但是除非必须,否则我不建议这样做,因为很容易引起死锁。一定要用的话必须先阅读<<Windows核心编程>>和<<Win32多线程程序设计>>这两本书。

 

COM+导致的变化:

上下文概述:

COM+对于套间的概念进一步的扩展,要求每个对象都必须运行在上下文中。通过上下文来控制对象的线程同步。

套间被细分为一个或者若干个上下文。一个上下文只能在一个套间中。一个套间至少包含一个默认上下文。

位于同一个套间中的不同上下文之间的对象调用必须经过轻量级代理的列集。轻量级代理不同于套间之间的代理,因为性能损失较小。

 

一个没有被COM+托管的传统COM组件不使用轻量级代理。但是该COM组件将被认为是放到了它所生存的套间的默认上下文内部,该套件的其他上下文(如果有的话)访问默认上下文不需要轻量级代理,默认上下文的引入只是为了和COM+上下文的概念一致。

 

上下文对象:

       上下文对象具体代表了每个上下文。CoGetObjectContext用来获取当前对象所在的上下文对象。

       上下文对象暴露了IObjectContextInfoIContextStateIObjectContextIObjectContextActivity四个接口。后面两个接口是向后兼容MTS,可以忽略。

       IObjectContextInfo::GetContextId方法可以获得上下文ID,调试时使用很方便。但是注意,只有COM组件被COM+管理后才能获得上下文对象,否则CoGetObjectContext将返回E_NOINTERFACE并返回NULL接口指针。所以如果我们开发的组件要同时适用于COM+和传统COM两种情况,就必须对CoGetObjectContext返回值进行查询并且作区分处理。

 

调用对象:

       当客户通过COM+服务调用COM对象时,COM+将创建名为“调用对象”的临时对象代表客户对COM对象的调用。调用对象将在方法返回后被销毁。

       调用对象暴露了两个与安全性设置相关的接口。

       CoGetCallContext函数可以让对象获取自己的调用对象,如果返回RPC_E_CALL_COMPLETE,则说明目前没有客户调用自己。

分享到:
评论

相关推荐

    《com原理与应用》高清版的pdf

    4. **线程模型与多线程COM**:COM支持多种线程模型,包括单线程公寓(STA)、多线程公寓(MTA)和自由线程(Free Threaded)。这部分会解释这些模型的差异以及如何选择合适的模型。 5. **注册与定位**:COM组件的...

    COM原理与应用 COM原理与应用

    5. **线程模型(Threading Models)**:COM支持多种线程模型,如单线程公寓(STA)、多线程公寓(MTA)和自由线程(Free Threaded)。线程模型决定了组件如何处理来自不同线程的调用。 6. **接口继承(Interface ...

    《COM 原理与应用》例子源代码

    COM组件遵循一套严格的规则,如单一线程激活(STA)和多线程激活(MTA)模式,以及延迟绑定和接口指针的引用计数等。其中,引用计数是COM管理组件生命周期的关键机制,当引用计数为零时,系统会自动释放该组件的资源...

    com 原理与应用

    通过这三本书的学习,您将能够全面理解COM的底层机制,包括组件注册、接口查询、多线程协作等,并掌握如何设计和实现符合COM规范的组件。此外,对于COM的高级特性,如分布式COM(DCOM)、COM+服务和ATL(Active ...

    com原理与应用

    四、COM多线程模型 COM提供了多种多线程模型,如STA(Single Threaded Apartment)、MTA(Multi Threaded Apartment)和Free-threaded,以适应不同类型的组件和应用场景。 五、COM应用领域 1. OLE(Object Linking ...

    COM原理与应用源码

    3. 异步和线程安全:COM支持多线程环境,源码可能展示了如何在不同线程间安全地调用COM组件的方法。 4. 智能指针的使用:如CComPtr、CComQIPtr等,它们自动管理COM接口的引用计数,防止内存泄漏。 5. 隔离和延迟加载...

    COM 原理与应用源代码

    这个压缩包文件“COM 原理与应用源代码”很可能包含了关于COM技术的详细解释和实际示例代码,帮助开发者深入理解和应用COM。 首先,COM的核心概念是接口。接口在COM中扮演着关键角色,它定义了一组方法,而这些方法...

    COM原理与应用pdf与源码

    8. **线程模型**:COM组件可以设定为单线程公寓(STA)、多线程公寓(MTA)或自由线程(Free Threaded)。这决定了组件如何处理来自不同线程的调用。 9. **延迟绑定与早期绑定**:COM支持两种绑定方式。早期绑定是...

    COM原理与应用+COM本质论

    4. **线程安全**:COM支持多线程访问,提供了同步机制来确保数据的一致性。 5. **延迟加载**:COM对象可以按需创建,降低了内存占用。 学习COM,首先要理解COM的基本概念,如组件、接口、实例、引用计数、 ...

    com 组件原理与应用源码

    "com组件原理与应用"这本书籍深入浅出地讲解了COM的核心概念、设计原则以及实际应用。 COM组件的核心原理主要包括以下几个方面: 1. **接口(Interface)**:COM组件通过接口与外界交互,接口定义了一组方法,这些...

    COM原理与应用 代码

    此外,你还可以通过这些示例学习到如何处理COM组件的错误,以及如何利用COM的特性,如延迟加载(Lazy Loading)、安全性和多线程支持。通过实践,你将能够更深入地理解COM在实际开发中的应用,并提升你的编程技能。 ...

    com原理与应用(潘爱民 编著)

    最后,通过阅读《COM原理与应用》,读者不仅可以理解COM的基本原理,还能学习到如何在实际项目中应用这些知识,例如构建自己的COM组件,或者利用已有的COM组件解决问题。书中的案例和实践指导将帮助读者将理论知识...

    com原理与应用源码

    2. 多线程 apartment (MTA):多个对象可以并行运行在同一线程上下文中,适合服务器端多线程应用。 3. 线程无关 (Neutral):对象可以适应任何线程模型,但需额外的同步机制。 四、COM激活 1. 内部激活:对象在同一个...

    COM原理与应用

    同时,COM还支持单线程和多线程 apartment(MTA 和 STA)模型,以处理不同线程环境下的对象交互。 在实际应用中,COM广泛应用于Windows系统和应用程序的组件化开发。例如,OLE(Object Linking and Embedding)技术...

    COM原理与应用源代码

    "COM原理与应用源代码"这个资源可能包含了关于COM组件创建、接口实现、组件注册、线程模型应用以及错误处理等方面的示例代码。通过学习这些源代码,你可以深入理解COM的工作机制,掌握如何在实际项目中应用COM技术,...

    COM 原理与应用.rar

    6. **线程模型**: COM支持多种线程模型,如单线程非 apartment (STA) 和多线程 apartment (MTA),以及线程无关 (Free) 等,用于处理线程间的通信和同步。 7. **激活**: 当一个组件需要被使用时,需要进行激活,这...

    易语言源码多线程多任务下载软件.rar

    本文将深入探讨易语言编程环境、多线程技术和多任务处理在软件开发中的应用。 首先,易语言是中国本土开发的一种面向对象的编程语言,以其“易学易用”的特点受到初学者和专业开发者喜爱。它采用中文语法,降低了...

    COM原理与应用书籍源代码

    6. **线程安全**:COM支持多线程访问,有 apartment threading(线程公寓)和 free threading(自由线程)两种模型,理解并掌握它们的区别和应用场景。 7. **延迟绑定**:COM支持接口的延迟绑定,即在运行时确定...

Global site tag (gtag.js) - Google Analytics