AutoCAD 3DMAX C语言 Pro/E UG JAVA编程 PHP编程 Maya动画 Matlab应用 Android
Photoshop Word Excel flash VB编程 VC编程 Coreldraw SolidWorks A Designer Unity3D
 首页 > VC编程

公寓间的线程调度问题

51自学网 2015-08-30 http://www.wanshiok.com

  一时灵感涌现,有所顿悟,遂记录下来。注意不保证正确性。

  我们知道公寓只是个逻辑概念,操作系统只为线程进程分配资源,不会为公寓分配资源。当客户程序调用 CoInitializeEx()时指定公寓类型,是STA还是MTA,只有COM才用到公寓这个概念。那为什么要创建这样一个概念,从根本上说是为了实现在多线程中同步地访问组件,尽可能地为我们编写组件制造方便,免除我们必须自己实现同步控制的麻烦。那它是怎么实现的呢?

  对于STA来说,我们知道当以COINIT_APARTMENTTHREADED参数调用CoInitializeEx()的时侯,系统会自动创建一个隐含的窗口。该隐含窗口的消息队列被用于同步化并分派对该STA内创建的对象的方法的调用。在这个公寓外其他线程要想调用该公寓内的对象方法,都必须先放在消息队列里,因为消息队列是线性的,所以自然而然的就解决了同步问题。对于MTA也应该是类似的方法,虽然书上没有说,但我想MTA公寓一样会有一个隐含的窗口。

  公寓间必须要调度,这句话包含了两个方面的意思,也即是包含了两种调度。第一个调度是指在公寓间调度接口指针。调用一个对象的方法,首先就是要获得它的接口指针。COM的接口指针是与公寓相关的,显然它们不能直接被某线程用于其它公寓。那样的话就等于跳过了消息队列而直接调用对象了,没法保证同步性。所以这时必须要调度。调度方法很简单,假设在STA2中要得到STA1中的一个对象的接口指针,则在STA1线程里通过调用CoMarshallInterThreadfaceInStream把对象接口指针调度到一个流对象内,然后在STA2线程内通过调用CoGetInterfaceAndReleaseStream反调度该流对象并获得一个指向代理的指针,这个代理在STA2内,并与STA1相关。要注意到的是,STA2得到的指向代理Proxy的指针,而不是直接指向对象接口的指针。第二个调度就很自然了,每当STA2要调用STA1中的接口方法时都要通过Proxy,这也叫调度。

  联系到前面讲到的公寓使用窗口消息队列来实现同步化的方法,我们可以猜测这里代理的作用是与这个消息队列相关的。很可能代理就是简单的把对方法的调用放到窗口的消息队列中。

  公寓间的这种调度与进程间以及远程间的调度显然是有根本区别的,这一点从另外一个角度也可以看出来。公寓间的调度并非是必须的!如果组件自身已经实现了同步控制,那公寓间的调度就是完全没有必要的了,因为我们说过公寓的作用完全在于帮助我们实现同步访问问题。既然我们可以通过自由线程调度器FTM来跨过公寓间的调度而直接调用接口方法,那也可以看出,公寓间的调度不是必须的!进程间以及远程间的调度肯定都是必须的,那这两种调度之间的区别何在呢?后者的调度产生原因在于进程处于不同的地址空间,甚至是在不同机器上的,需要调度解决这个问题。既包含调度接口指针,也包含了更为重要的参数打包解包的调度。但对于公寓间的调度不存在这个问题,因为公寓的一个基本点在于它是存在于一个进程内的。所以它不需要完成不同地址空间的映射,不需要把函数参数打包解包,它的调度的目的完全是不同的。另外我们也注意到,公寓间的调度只有代理Proxy,没有存根Stub。这也应该证明了我们的猜想吧,公寓间的调度只是为了解决同步性问题,代理的作用仅仅是把函数调度放到消息队列中。

  以上内容可以总结为以下几点:

  1、MTA公寓也有一个隐含窗口,也是通过窗口消息队列来实现同步性的。

  2、公寓间必须调度接口指针,调度的结果是获得一个指向代理的指针。

  3、公寓间的接口方法调用,必须通过代理来实现。

  4、公寓间的调度完全只是为了实现同步性。

  5、公寓间的调度只有代理没有存根。

  6、代理的作用只是简单的把接口的方法调用放入窗口消息队列中。

 

 

 
说明
:本教程来源互联网或网友上传或出版商,仅为学习研究或媒体推广,wanshiok.com不保证资料的完整性。
上一篇:VC++ 的串口通讯  下一篇:使用Visual C++开发SOAP客户端应用