一点心得:组件的线程模型

艺赛旗-norman66 2003-05-16 04:14:22
关于组件的线程模型

一,两种线程模型
STA(Single Threaded Apartment)
  在STA模型中,一个Apartment里只允许有一个线程,可以有多个实例,一个进程中可以有多个STA。每个STA里都必须有消息处理部分。所有对实例的访问都在WINDOWS的消息传递机制下,被线程串行化了。套间与套间之间可以并发执行。

MTA(Multiple Threaded Apartment)
  在MTA模型中,一个Apartment中可以有多个线程,但是一个进程中只有一个MTA。MTA中不需要消息处理。

(其实在WINDOWS2000还有第三种模型NTA,由于暂时用不到那么高级的功能特性,因些没有去了解和掌握它。)
任何要用到COM的线程,都需要标明它的线程模型,而且一旦标明线程模型,线程的同步性便不能更改。很明显,客户端和服务端都需要标明其线程模型。

二,线程模型的联系
这里只考虑进程外服务。由于进程外服务和客户程序属于不同的进程,从而必定属于不同的APARTMENT,而COM规定,套间(Inter-apartment)联系必须列集(Marshal)。也就是说不论客户与服务组件联系肯定要通过列集,而列集可以掩盖它们的不同的线程模型。

在STA中,由于只有一个线程,线程中的多个实例会相互干扰。如果客户端是STA,那么其中所有实例的方法必定完全是顺序执行的,这很容易理解。如果服务端是STA,那么所有客户对组件方法的调用也都是串行的,也就是说,即使客户端是并行调用一个实例的一些方法,实际执行时仍是串行执行的。除非客户端和服务端都是MTA,在一个客户端才能实现并行访问。当然,如果服务端是MTA,而客户端是STA,那么多个客户的访问是并行的,而在一个客户内部的访问是串行的。

三,组件的线程模型
组件的线程模型分为四种:Single, Apartment, Both, Free。简单地说,它们分别对应:STA(main),STA,STA and MTA, MTA。对象的线程模型的含义是“它生活在什么样的线程模型里”,就好像划成分一样,一出生就确定,然后就不能再改变。

根据MSDN上的说明,尽量不要用Single和Free,所以这里只讨论Apartment和Both。Apartment类的对象只能生活在STA中,如果服务程序本身是STA,那么它就不得不重新为每个实例生成一个新的Apartment。由于服务程序和组件生活在不同的套间,每次访问都不得不进行套间切换和列集,这样是非常低效的。但如果服务程序是STA,那么就可以直接调用了。Both类的对象即可以在STA中,也可以在MTA中,不管服务程序属于哪一类,都可以直接调用,因此非常高效。

Apartment的优势在于它不必是线程安全的,但对于全局变量和静态变量,仍然要提供同步保持机制。Both类的对象必须是线程完全的。
...全文
77 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
yongyu2000 2003-07-14
  • 打赏
  • 举报
回复
VB程序本身也是在STA中运行的
在STA中的程序调用both or apartment的组件,这个组件本身在同一个STA中被创建
(深入理解COM+, p44)

phonlee(not a bird,but ...) ,我也不太肯定我的分析,欢迎大家一起讨论。
yongyu2000 2003-07-14
  • 打赏
  • 举报
回复
我没有看到你的代码,不敢肯定
你两次调用的组件在同一个STA中吗?
VB在调用COM做了很多我们不知道的操作,建议你把测试代码用SDK写一遍

我觉得只要是针对同一个STA里面的组件发起调用,那肯定会被堵塞。
phonlee 2003-07-14
  • 打赏
  • 举报
回复
2 yongyu2000(The Power of .NET)
有什么问题请指正!
luohualiushui 2003-07-13
  • 打赏
  • 举报
回复
这种贴子顶了再看
yongyu2000 2003-07-13
  • 打赏
  • 举报
回复
再跟一贴,两本好书

深入理解COM+

作者:(美)David S.Platt
定价:¥25.0
出版社:清华大学出版社
出版日期:2000-04-01

COM+与Visual Basic 6分布式应用程序设计(第2版)

作者:(美)Ted Pattison
定价:¥55.0
出版社:机械工业出版社
出版日期:2001-06-01
yongyu2000 2003-07-13
  • 打赏
  • 举报
回复
答xiaohyy(醉大饿极),如果你不是用VB写COM+,而是用ATL的话,一般是推荐使用NA的。
就是作者说的那个NTA。
yongyu2000 2003-07-13
  • 打赏
  • 举报
回复
phonlee(not a bird,but ...) ,你的做法好像有问题....
feeboby 2003-07-12
  • 打赏
  • 举报
回复
学习中
phonlee 2003-07-12
  • 打赏
  • 举报
回复
靠!
这个线程模型让人晕呀!

我分别写了4个single apartment both free组件

每个组件都有一个函数:::test()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())
MessageBox(NULL,"QQQQQ","",MB_OK);
Sleep(10000);
return S_OK;
}


然后使用vb写的客户端掉用,同一个exe启动两分;

可是掉用的结果一样

client1调用test,showmsg then enter sleep
马上client2调用test也会showmsg

说明都没有block,结果都一致


K~~ 要什么thread model干什么??







xiaohyy 2003-07-08
  • 打赏
  • 举报
回复
在com+中通常用哪种线程模型??
Erlin 2003-07-07
  • 打赏
  • 举报
回复
Both类的对象即可以在STA中,也可以在MTA中,不管服务程序属于哪一类,都可以直接调用,因此非常高效!

不是这样的,Both类的apartment model与创建它的客户端的apartment model一致,也就是说,如是客户端是STA的,那么Both类的对象生存于STA中,如是客户端是MTA的,那么Both类的对象生存于MTA中。
________________________________________________________________________________

试想如果客户端采用的复合 apartment model, 在STA中创建BOTH类的对象,在MTA中调用时仍然是要列集的。

要不然,为什么还要有FREE类型的套间模型呢?
firingme 2003-07-07
  • 打赏
  • 举报
回复
jinnie()的说法是正确的。
STA下头,一个线程对应一个套间
艺赛旗-norman66 2003-07-05
  • 打赏
  • 举报
回复
HyChris:
我认为没有错,如果是MTA,所有实例都可以存在一个线程中,不会也没有必要生成新的Apartment.如果是STA,由于每个实例都不是线程安全的,所以需要单独的进程环境,也就是一个Apartment,这样才不会有错误。
zzyx 2003-05-30
  • 打赏
  • 举报
回复
why not up
HyChris 2003-05-28
  • 打赏
  • 举报
回复
如果服务程序本身是STA,那么它就不得不重新为每个实例生成一个新的Apartment
敲错了吧??STA这里应该是MTA
xiaohedou 2003-05-28
  • 打赏
  • 举报
回复
我也在学习COM中
alphapaopao 2003-05-21
  • 打赏
  • 举报
回复
学习
xiaohedou 2003-05-21
  • 打赏
  • 举报
回复
up

3,245

社区成员

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

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