关于COM 线程模型的概念性问题

deepwater 2000-09-03 06:05:00
小弟刚开始学习COM,有些线程模型问题不太清楚,请诸大虾指点一二:

1)如果我实现的一个组件做到 1.组件只包含一个线程 2.无论是组件还是客户都用CoIntialize初始化
那么可否说我的这个组件的线程模型是 Apartment ?
2)现按上述条件实现一个组件 C,实现一个接口 IX,接口中包含两个方法:A 和 B。A 中延时5秒,B 立即返回。
编译之得到组件及其代理。
在客户中,除自己的主线程 th0 外我额外创建一个线程称 th1,并且在 th1 中创建组件 C,并将 IX marshal给th0
这时无论我在 th0 还是 th1 中调用立即返回的IX::B,耗时都是10 ~ 20 ms。
如果我按下列顺序调用(在th0和th1均已得到了IX后):
1.首先在th1中调用延时5秒的IX::A
2.然后在th0中调用立即返回的IX::B
虽然调用发生在两个并发的线程中,但由于组件的线程模型为 Apartment (所有的COM初始化都调用CoIntialize),
故th0中的IX::B的调用其实会被COM转发到th1中进行,但由于th1此时正处在IX::A的5秒延时中,所以IX::B必须等待,
这样th0中的IX::B的调用应该超过5秒才对,但我却依然得到了20ms的结果,请问为什么?

估计我的概念上还有不清楚和错误的地方,股恳请诸大虾给我解惑!谢谢!
...全文
450 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
horris 2001-02-28
  • 打赏
  • 举报
回复
同步对象中的一类,它们每时每刻都有一个所有权的问题,即提到一个同步对象,它必有一个线程拥有它。而另一类不被任何线程拥有。第一类对象如果是自动复位的,对定时不会有影响,如果是人工复位的,可能有影响
deepwater 2001-02-28
  • 打赏
  • 举报
回复
>如果是用event,我记得event是从属于线程的,好象不太
event不是线程和进程间常用的同步对象吗?怎么会“从属于线程的”?
以下摘自MSDN>Paltform SDK>Windows Base Services>Interprocess Communication>Synchronization>Using Synchronization>Using Event Objects

"Win32-based applications use event objects in a number of situations to notify a waiting thread of the occurrence of an event. "
crm2000 2001-02-28
  • 打赏
  • 举报
回复
继续关注
horris 2001-02-27
  • 打赏
  • 举报
回复
1.VC6是缺省的线程模型是Apartment呀!
2.threading model分两方面,一方面,COM object本身支持什么模型,这是由其对实例数据和共享数据的同步方法决定的,并通过注册表的ThreadModel(in-process)表现出来,对引用记数的同步通过COM object class的基类CComObjectRootEx的模板参数指定,该参数可为CComSingleThreadModel,CComMultiThreadModel等。另一方面,调用COM对象的线程通过CoInitialize[Ex]表明自已参与进什么类型的线程模型。如果线程初始化的线程模型与COM对象所支持的不同,则COM为它们进行调度(Marshalling)
3.如果你的COM对象是支持Apartment的,则你的第二问th0应该是5秒以上。我想问几个问题:
1。你是怎么知道你的对象是支持STA而不MTA或Both的
2。你的COM server是in-process还是out-of-process
3.你怎么保证th1调用IX::A肯定在th0调用IX::B之前?这可是独立运行、不能预言谁先谁后的两个线程啊!
4。你的怎么计时的?
horris 2001-02-27
  • 打赏
  • 举报
回复
得到的是什么预期结果?5s+20ms?那我明白了,COM把你的对象当成MTA了,这时是上帝在保佑你的实例数据同步,如果你是用STA作的话。
timeSetEvent如果是用回调函数,因为回调函数不运行于调用者线程的环境中,所以定时是可靠的,但是这时涉及到三个甚至四个线程以及全局变量的同步;如果是用event,我记得event是从属于线程的,好象不太好
deepwater 2001-02-27
  • 打赏
  • 举报
回复
我当然保证:因为当th0收到消息准备调用IX::B前,要等待我设置的一个event,而这个event的状态是在IX::A开始运行时被设置的。

〉我是问你怎么保证你的记时方法是独立于线程的?
你可以去看看Multi Media的文档。

顺便说一句:我把注册表中的线程模型设置好后,就得到了预期的结果,那已经是4个多月前的事了。
horris 2001-02-27
  • 打赏
  • 举报
回复
错!你调用IX::A前PostMessage,不能保证该消息执行在A之后!!!你有可能有时得到20ms,有时得到5秒加20ms
我是问你怎么保证你的记时方法是独立于线程的?
deepwater 2001-02-27
  • 打赏
  • 举报
回复
这个问题如前面我2000-9-8日的post所述,我已经得到结论,因为我的组件是in-process,没有在注册表中指明线程模型,所以其实线程模型为free。
至于 horris 的问题:
>你怎么保证th1调用IX::A肯定在th0调用IX::B之前?
很简单的trick:我在th1中调用延时5秒的IX::A前向th0 PostMessage,通知 th0 调用 IX::B
>你的怎么计时的?
Multi Media Timer
veinstone 2001-02-24
  • 打赏
  • 举报
回复
参与
wudaqiang 2000-11-22
  • 打赏
  • 举报
回复
你好,我看到你在在CSDN上的帖子,目前我也正在做线程中访问COM组件的东西,
对这方面的东西不太懂,能否给点帮助。
1、我在VC6中建立的COM组件好像缺省都是both(MTS EXPLORE 中是这样写的),这会不会影响 到我在客户端线程中访问COM组件
2、客户端启动很多线程访问COM组件,每个线程可能调用COM中不同的接口函数,那么每个函数的返回值怎么对应到
每个调用它的线程中去呢?
3、每个子线程在得到返回值后,怎么把他们交给主线程去做相应的处理?(是不是可以用消息,告诉主线程返回值,应该怎么
做)

我做的com组件用ado访问后台Oracle8i数据库,组件放入MTS中使用。

谢谢
  • 打赏
  • 举报
回复
那分呢?
deepwater 2000-09-08
  • 打赏
  • 举报
回复
我自己解决了:
对于in-process的组件必须在注册表中注明线程模型

3,245

社区成员

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

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