好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

COM多线程模型.ppt

78页
  • 卖家[上传人]:野鹰
  • 文档编号:2937625
  • 上传时间:2017-07-28
  • 文档格式:PPT
  • 文档大小:374KB
  • / 78 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • COM多线程模型、DCOM,潘爱民 thread)包含消息队列,当线程首次调用Win32 User或GDI函数时产生常常包含消息循环,组合GetMessage/ TranslateMessage/DispatchMessage辅助线程(worker thread)一条执行线索,没有UI,没有消息概念,COM线程,按照COM对象的执行环境,分为套间线程和自由线程套间线程(apartment thread)位于一个STA中(Single-Threaded Apartment)一个套间对应一个线程自由线程(free thread)位于MTA中(Multi-Threaded Apartment)一个进程有一个MTA,它可以包含任意数量的自由线程,marshaling,调用者与被调用者如果位于不同的线程中,则调用过程要有两次线程切换,线程切换也需要用到marshaling机制COM对象的线程相依性有的COM对象只能在一个线程中运行内含UI的COM对象只能在创建线程上运行线程之间的marshaling机制与进程间的marshaling过程一致,同步,只能被一个线程访问的对象不需要同步例如Windows的窗口过程但是对于全局变量的访问,仍需要同步保护有可能被多个线程访问的对象需要有同步机制Event、Semaphore、CriticalSection、Mutex这样的代码被称为thread-safe,Apartment(套间),是一个逻辑概念,也有实体对应是COM对象的执行环境分为三种套间STAMTACOM+引入TNA(thread-neutral apartment) *,STA套间,每个STA套间包含一个线程STA套间和线程有一一对应关系当线程被创建后,用COM库初始化就建立起一个STA套间CoInitialize(NULL);或者CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);程结束之前,调用CoUninitialize结束套间套间线程包含消息循环COM在套间线程中创建了一个隐藏的窗口用途:同步、分发消息,STA套间(续),在STA中创建的COM对象都属于这个STASTA对象不必处理同步,因为对象的方法代码只能被这个STA套间的线程调用但DLL程序的引出函数如DllGetClassObject和DllCanUnloadNow等仍需同步处理。

      类厂是否需要线程安全,取决于类厂的策略如何把接口指针交给调用者自动marshaling手工marshaling,STA接收调用示意图,,,,,,STA,,,,,消息,隐藏窗口,,分发消息,,,,stub,stub,,,,STA套间传递接口指针,通过COM传递的接口指针,COM都会自动marshaling手工marshalingCoMarshalInterface和CoUnmarshalInterfaceCoMarshalInterThreadInterfaceInStream和CoGetInterfaceAndReleaseStream,套间线程要点,STA客户调用STA对象的过程RPC通道,通过消息传递调用,RPC通道发出消息后,调用MsgWaitForMultipleObjects阻塞调用方,但仍然分发消息,所以UI仍是活的STA客户跨进程调用的过程代理对象先得到一个RPC线程,并把列集后的数据包交给它,RPC线程又生成辅助线程,由它负责跨进程调用,RPC线程也负责分发消息,所以UI也是活的从另一个进程进入套间线程的过程调用首先到达一个RPC线程,RPC线程向套间线程隐藏窗口发送消息,并把列集数据传过去,套间线程:典型情形,客户创建套间线程,然后套间线程的主函数创建COM对象,套间线程再调用CoMarshalInterThreadInterfaceInStream函数,把接口指针列集到流对象中,然后通知客户线程对象已经创建成功,客户线程接到通知后,利用流对象指针把对象的接口指针散集出来,以后客户线程就可以与对象通讯了。

      STA,Main STA,,通过流来传递,MTA套间,每个进程至多只有一个MTA套间MTA套间中可以包含一个或者多个线程线程初始化: CoInitializeEx(NULL, COINIT_MULTITHREADED);Windows的版本:NT 4.0或者Windows 95 + DCOM扩展MTA套间中的对象必须thread-safe被MTA中线程创建的对象为MTA对象MTA中的线程都可以直接访问MTA对象使用Win32多线程编程技术保证thread-safe,MTA接收调用示意图,,,,,,MTA,,,,,调用,,,stub,,,stub,,,,,MTA线程,RPC线程,MTA中线程的特点,使用CoInitializeEx(NULL, COINIT_MULTITHREADED)初始化若客户与对象都在MTA中,则调用直接在客户线程中执行若客户程序在另一个进程中,则调用通过proxy/stub,直接在RPC线程上执行若客户在STA中,则调用通过proxy/stub,直接在RPC线程上执行没有隐藏窗口,MTA线程创建的对象并没有生存在任何特定的线程中,而是生存在MTA中MTA对象必须是线程安全的,允许重入,MTA线程要点,MTA线程中的客户调用STA对象或其他进程中的对象客户调用代理对象,代理对象又调用RPC通道,RPC通道阻塞客户线程,如果客户线程中有窗口的话,则会被锁住调用进入MTA线程中的对象RPC通道直接使用RPC线程,并调用存根代码,存根再调用组件对象。

      这中间没有线程切换总结:STA和MTA之间关系,不同进程之间,不管什么线程类型,都需要proxy/stub在同一个进程内不同STA之间,也需要proxy/stub在STA内部,一个对象调用另一个对象的方法不需要proxy/stub在MTA内部,对象和调用者之间调用不需要proxy/stub从STA调用MTA,需要proxy/stub从MTA调用STA,需要proxy/stub,进程内的STA和MTA,,,,,,STA,,,,,STA,,,,,MTA,,,进程,进程内对象的线程模型,CLSID\{clsid}InprocServer32ThreadingModel = “Apartment”或“Free”、“Both”DllGetClassObject和DllCanUnloadNow同步当COM库创建对象时如果客户线程模型与对象的要求一致 则在客户线程中创建对象,返回直接指针如果客户线程模型与对象的要求不一致: COM会产生一个相应的线程供对象使用,“Both”类型,这种对象必须是thread-safe它总是位于创建者的套间中本质上具有“Free”对象的特性,但是在运行时刻可能会表现出“Apartment”对象的特性例子:接口proxy/stub都是“Both”类型,Main STA,第一个STA,往往是进程的主线程如果一个COM class的ThreadingModel值为空,则默认为Main STA在引入MTA之前的对象都使用Main STA,客户线程与对象模型组合表,进程外对象的线程模型,与客户线程模型没有关系由组件服务程序自己来控制类厂对象通过CoRegisterClassObject来传递类厂的CreateInstance函数,COM+增强,环境对象的执行环境,包含环境信息,如事务、安全性等在原来的模型中,我们认为MTA和STA就是一个执行环境跨环境调用也需要proxy/stub轻量代理不需要线程切换的跨环境调用TNA(Thread neutral apartment),COM+环境,从进程内走向进程外 进程透明性,从本机走向远程主机 DCOM,预备:RPC(Remote Procedure Call),RPC Client and RPC Server可以在TCP、UDP上实现RPC是分布式应用的基础,过程如下:客户准备:三元组(远程机器、server、函数)在RPC Server上需要运行一个RPC端口管理服务,每个RPC Server向它登记注册RPC client与远程机的RPC端口管理服务联系,请求RPC Server的端口号然后RPC client与RPC server直接联系其他远程调用途径,如HTTP、SOAP,DCOM要点,创建远程对象把进程内对象放到远程机器上DCOM的连接管理DCOM并发性管理DCOM安全性,DCOM组件对象的创建过程,对象激活(activation),对象激活:创建新的组件对象——类厂对象建立已有组件对象与客户之间的连接——名字对象远程对象的创建:标识一个远程对象:CLSID+RemoteServerName如何获取RemoteServerName 信息DCOM配置工具指定远程服务器名客户程序在代码中显式指定远程服务器名,创建DCOM组件(一),位置透明性:客户程序不必知道组件运行在本地或远程机器上RemoteServerName信息: HKEY_CLASSES_ROOT\APPID\{appid-guid} “RemoteServerName”=“” HKEY_CLASSES_ROOT\CLSID\{clasid-guid} “AppID”=“”RemoteServerName信息不能被传递客户创建组件对象的代码不必修改,使用DCOM配置工具配置组件的RemoteServerName信息,创建DCOM组件(二),在CoGetClassObject和CoCreateInstanceEx函数中指定服务器信息 typedef struct _COSERVERINFO { DWORD dwReserved1; LPWSTR pwszName; COAUTHINFO *pAuthInfo; DWORD dwReserved2; } COSERVERINFO; typedef struct _MULTI_QI { const IID* pIID; IUnknown * pItf; HRESULT hr; } MULTI_QI;,。

      点击阅读更多内容
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.