COM新手:------请高手详细谈一下COM的线程模型

zhf406 2001-11-11 03:39:15
...全文
185 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
yoshiyan 2001-12-27
  • 打赏
  • 举报
回复
在MTA中运行COM对象的最大好处是,真正多线城模式的对象可提供更好的性能.然而,能够运行在MTA中的对象太复杂了.
在WINDOWS 2000 中套间已不象以前那么重要了.主要原因在于,COM+利用环境(CONTEXT)的概念改造了套间的概念,他允许使用一个新的选择方案,称为标准套间(NEUTRAL APARTMENT)
yoshiyan 2001-12-27
  • 打赏
  • 举报
回复
为了更好的管理线程,com引入了套间的思想.每个进程包含一个或多个套间.如何一个正在执行的com对象一定位于某个套间中.套间又分两种;单线程套间(STA single_thread apartment)和多线城套间(MTA multiply-thread apartment)
一个进程可以同时有多个STA只能有一个MTA
STA内只有一个线程,套间中所有的对象共享该线城,任何给定一个时刻,特定STA中只能有一个对象在执行.而MTA中有多个.
在STA中运行COM对象的一个好处是,这些对象的开发人员不需要为并发访问而操心.因为套间中只有一个线城,所以同一时刻该套间中只能有一个对象的一个方法在执行.这个进程做为一个整体仍是多线城的-每个STA都有自己的线城-但是开发人员的工作则大大简化了.
sogald_2001 2001-11-12
  • 打赏
  • 举报
回复
上面那幅图可以参考潘爱民翻译的《深入理解COM+》
sogald_2001 2001-11-12
  • 打赏
  • 举报
回复
先谈 APARTMENT
APARTMENT类似于一间房子。房子的门和墙类似于一组规则,并且不允许打破。一个线程只能驻留在一个APARTMENT中,就像一个人不能同时存在于两间不同的房子中一样。一个COM实例也只能存在于一个APARTMENT中。但是,就像一间房子不止能容纳一个人一样,一个APARTMENT 中可能存在多个COM实例。

STA:
STA是一种单线程单元模型。STA的创建通过调用函数 :
CoInitializeEx(NULL,COINIT_APPARTMENTTHREADED) 来创建。函数CoInitialize()的效果和它一样。都是用来创建一个STA。COM规定:任何进程内服务器第一次被装载时,它将处于一个“已经加入了某个APARTMENT”的线程环境中,任何调用 CoCreateInstance 或者
CoGetClassObject 的线程必须已经加入到一个APARTMENT,否则调用会立即失败。这就是为什么我们创建COM实例的时候,第一个要调用的函数就是CoInitializeEx或者CoInitialize
的原因。任何线程一旦调用了函数CoInitialize或者以参数COINIT_APARTMENTTHREADED调用了CoInitializeEx都将使COM创建一个隐藏的窗口把对当前APARTMENT中的对象的请求排队。为了服务这些请求,线程必须使用一个Windows消息循环。例如:
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR,int)
{
CoInitialize(); //这将创建一个APARTMENT
......
MSG msg;
while(GetMessage(&msg,0,0,0) ) //在这个消息循环中处理上面创建的APARTMENT
DispatchMessage( &msg ); //中的对象的请求。

CoUninitialize();
}

所以,同一个APARTMENT中的对象不需要我们编写额外的代码来实现同步。但是,对象的静态和全局数据仍然需要同步。并且,在不同的APARTMENT中的对象要通讯就必须经过调度(MARSHAL),CoMarshalInterThreadInterfaceInStream等函数就是打开APARTMENT那间房子的门的钥匙。这是一个开销很大的过程。为此引进了MTA。

MTA:
MTA是以参数COINIT_MULTITHREADED调用CoInitializeEx函数来创建的。MTA中的对象可以相互自由通讯,但是我们必须编写同步的代码来保护数据。考虑到性能问题和为了简化操作,COM+引进了NA(Neutral Apartment).

NA:
这是在COM+中引入的。NA中不包括线程,只有对象。当一个线程通过代理(Proxy)调用到NA中的对象时,调用过程不改变线程,这使得调用过程比标准的 线程-切换代理调用快得多。这也意味着不管调用者线程属于什么类型,NA中的对象总是在其调用者线程中接收调用。如果STA线程 调用了NA对象,则调用将在STA线程中进行。对MTA也一样。NA对象所要求的同步处理由COM+处理。 NA可能会取代FREE和BOTH两种线程模型。


我用一幅图总结一下:

-------------------------------------------------------------------------------
| 进程
| ----------------------- ------------------------------------
| | STA1 | | STA2 |
| | | | |
| | 线程1 | | 线程2 |
| | _______ ______ | | |
| | |对象 | |对象| | | ________ _______ ________ |
| | |1-A | |1-B | | | | 对象 | | 对象 | | 对象 | |
| | ------- ------ | | | 2-A | | 2-B | | 2-C | |
| | | | -------- -------- -------- |
| ----------------------- ------------------------------------
|
| ------------------------------------------------
| | 对立的MTA |
| | ________ |
| | 线程3 | 对象 | |
| | | MTA1 | |
| | -------- |
| | ________ |
线程4 | 对象 | |
| | | MTA2 | |
| | -------- |
| 线程5 |
| ------------------------------------------------
|
|-------------------------------------------------------------------------------
wyzegg 2001-11-11
  • 打赏
  • 举报
回复
一个进程可以有多个STA只能有一个MTA
COM对象一定要驻留在一个APARTMENT里
STA只可以供一个线程访问,STA的同步是用一个隐藏窗口的消息循环来完成
MTA可以有多个线程同时访问,所以组件必须是线程安全的
垮APARAMT访问组件需要调度接口CoMarshalInterThreadInterfaceInStream和
CoGetInterfaceAndReleaseStream可以帮助实现
FTM和GIS可以帮助对不同的类别套间里的对象的访问
客户程序和服务器APARMENT的类型一致时可以获得最佳性能,否则需要调度
推荐使用NA

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧