首页 > 代码库 > com线程模型01

com线程模型01

Coinitialize;

IUnknown;

apartment;

 

《com技术内幕》《com本质论》《COM技术内幕》《深入理解COM+》

-------------------------------------------

随笔分类 -J.COM技术:

http://www.cnblogs.com/Clingingboy/category/198480.html

关于com套间的资料:

目前发现仅此一篇完整,不过国人可笑的是骂的人居多讨论的人却很少

http://www.vckbase.com/document/viewdoc/?id=1597

下面这个帖子的讨论也很精彩

http://topic.csdn.net/t/20021117/21/1184068.html

 

关于COM及套间(Apartment)知识

http://blog.csdn.net/wojiaopanpan/article/details/7574961

com与套间之我见:

http://www.fx114.net/qa-211-55637.aspx

 

请解释COM中 apartment (套间)的含义 :

http://bbs.csdn.net/topics/20121276

VC知识库:

http://www.vckbase.com/index.php

==================================

代理存根就像你和你女朋友打电话,你拿着话筒说,她拿着话筒听,说什么不重要!
你拿的话筒相当于代理,她拿的相当于存根,中间的实现过程你不用关心,主要是传输的语音是彼此的就好了!
套间相当于给COM组件加了一个外壳
我们用房子代表套间,人代表COM组件,每个房子里有一台电脑

单线程套间(STA)
    这个房子只能容一个人A,这个人使用电脑,可以直接用(线程间在同一个
    内存地址,故不用使用代理),应为他在一个房子里。而这个房子外面的
    人B(代理),想用他的电脑,必须来敲门,但是由于使用的人多所
    以需要排队(隐藏窗的作用先进先出原则)等候,等到轮到他的时候,
    A打开门(存根) 让B进去,A就出去了,因为我门假定房子只可以容一个人。
    这样就避免了,线程之间的同步交互赛跑问题。
多线程套间(MTA)
    就是相当这个房子比较大,房子中有一台电脑,但可以容纳很多人A,B
    C,D,E在另一个房子里,C要使用那个房子的电脑,必须和STA一样,
    通过存根代理!
    但是MTA的问题就出来了,A,B如果抢电脑用,怎么办?
    这个就是程序员需要编程控制的事了!
租用线程套间(RTA)
    房子是空的,电脑也闲着。
    有人想进去,直接进去就可以了,不用使用存根和代理。
    但是有人进去了,又有人想去玩电脑。就要在门外面等着里面的老先生
    玩爽了,玩够了,出来了,才能进去。这由要使用代理与存根,
    但这个仅仅是一个概念,微软只是提了提!!这里你就不用关心了!

-----------

你的比喻还是相当精彩,不过可能有点问题。如你所说,房子代表套间,人代表COM组件对象。“单线程套间(STA)就是 这个房子只能容一个人A”,这应该是你的意思吧?但是STA中应该是能同时存在多个COM对象的。我想是不是应该把“电脑”比作COM对象、“人”比作线程更恰当一些。比如:
    单线程套间(STA):这个房子(STA)只能容一个人(套间线程),可以有多台电脑(COM对象)。当然这个人一个时刻只会用一台电脑。房子外面的人(其他套间线程或自由线程)想访问这个房子里的电脑(COM对象),必须要通过这个房子中的人(STA中的套间线程)制定的某些调用规则(消息队列)才行!

--------------------------------

首先我们来考察这样一个问题:如果我们创建了一个COM对象,那么它的实体到底在哪里?简单的说,是在套间(apartment)里面,那么套间又是处于何处呢?我想后一个问题正是我们所困惑的。那么不妨看看这样的一个windows下的事实:我们的程序如果调用了dll,那么dll在哪里?如果多个程序调用了一个dll,那么这个dll在哪里?答案是第一个dll在启动他的程序地址空间里面,后来启动的dll并没有真正的载入,仍然是使用原有的dll,至于如何在不同的进程之间(这通常是程序的最大边界)协调这些东西,这时windows的事情,我们不需要管他。事实上,dll已经处于这样一个地位:一方面它是从属于某一个应用程序的,一方面它又能自由的跨越进程(当然有限制,而且只有系统才能做),这种两重性质,与进程非常不同,我们甚至可以假想它生活在一个独立的空间,谁来它就服务谁--而这正是COM生存的最理想的方式。由此做为类比,我们就不难理解套间的概念了,套间正是这样一个只受系统约束的“独立的空间”,它是COM对象“出生和死亡”的地方,也是应用程序需要COM对象时的访问之所。套间大小可大可小,位置也很随意,大小可以从dll到应用程序,甚至系统全局,位置可以就在dll中(也就是进程中),也可以超乎进程外,甚至跨越系统和网络(DCOM正是如此)。套间因为有了系统的帮助而获得了近乎自由得权利,那么显然应用程序不能按自己的意愿肆意的来访问(不良的操作最多死机,恶意的操作可能就是另外一个CIH了^_^)。怎么访问套间,正是我们需要解决的另一个问题。(此上对于套间其实做了一个简化的概念上的讨论,我觉得对于理解其实应该正好,具体的规范大家参考《COM本质论》吧)

访问套间的方法,就是COM中的接口,也就是说我们只能让用户访问到COM对象的服务功能,而不能让用户访问其私有的数据(通常这就是系统稳定和安全问题的关键所在)。COM的二进制意义上接口已经为我们提供了良好的条件,它能够从一个接口点出发访问到所有,也能从一个传递到另一个,自身(即符合了自反,传递,对称,形成一个闭包)。既然有了一个接口就相当于撬起来了地球,剩下的问题就是,我们需要借助一种什么力量获得这第一个接口呢?谁有这么大的力量呢?我想这个时候,大家都已经知道了,就是windows系统了。系统赋予我们这样的能力,但是也是有限制的:要么在创建COM对象时,通过一个IUnknown接口给我们对象的第一个接口(也就是CoCreateInstance函数里面那最后一个参数了,千万注意哦^_^);另一个方式就是我们的包容在Advise向OLE对象注册自身之后,OLE对象会通过SetSite函数将自身的IUnknown接口通过参数传递过来(Yehh,bingo!)。除此之外,我想除非你和Bill哥哥关系密切,那么也许windows会考虑网开一面的^_^。

有了阿拉丁神灯“IUnknown”,我们就可以根据COM对象的类型来查询其支持的各种各样的接口了。举例子来说,我们可以根据文档(例如MSHTML就有很好的文档支持)得到接口的IID,然后查询,进而得到更多的接口;或者(例如WORD等等不知道IID的)我们可以完全的就通过其IDispatch接口来invoke所有的功能(DISPID可以通过在MFC工程中添加包装类从包装类的实现中得到)。现在,是不是有一些“给我一个接口,我就能驱动地球”的感觉了^_^

com线程模型01