STA(单线程公寓)COM对象 - 产生工作线程?

时间:2011-03-24 17:26:33

标签: c++ multithreading com

在STA COM对象中生成工作线程是不是坏事(即COM对象创建一个线程来执行任务)?我想,答案是 - 这取决于!

例如在我的情况下: 我正在使用的工作线程不会干扰/访问COM或COM服务。

我之所以这样问是因为STA COM定义STA只能容纳一个线程。产生多个线程有点违背这个原则,除非工作线程和它们的工作不干扰/处理COM / COM服务。 在这种情况下,我认为这是完全正常的,在我看来,COM不应将工作线程视为逻辑STA的一部分。

您对此有何看法?

3 个答案:

答案 0 :(得分:2)

不,这不是一件坏事。公寓明确存在,以帮助您获得多线程代码。 STA线程是COM服务器的安全主页,它不是线程安全的,COM的单元线程模型确保它始终以线程安全的方式使用。您所要做的就是编组要在工作线程中使用的接口指针(例如IGlobalInterfaceTable),您可以在不做任何特殊操作的情况下调用方法。

这当然不是免费的,编组电话会产生开销。多少取决于STA线程在泵送其消息循环时的响应程度。如果您打算明确地创建工作线程以便以多线程方式使用该COM服务器,那么当然您不会领先,而是让它变慢。

答案 1 :(得分:1)

不要让工作线程以任何方式使用COM,你应该没事。这意味着您无法在worker中调用COM对象,也无法直接或间接地从worker调用COM运行时API。

答案 2 :(得分:0)

要实现的重要一点是,您创建的任何新线程本身都是新线程;它实际上并不重要哪个线程创建它们。重要的两件事是:(1)那些新线程本身调用CoInitializeEx并且每个都获得自己的STA,或者共享一个MTA,以及(2)在线程之间传输的任何COM对象指针都得到适当的封送。不要只是在全局变量中将COM对象指针从一个线程传递到另一个线程;而是根据需要使用GITCoMarshalInterThreadInterfaceInStream

(一个例外:您可以在MTA线程之间自由传递COM指针;但只有一次该指针已被适当地封送到MTA中。)

另外,你需要非常了解那里的物体以及它们的亲和力。如果您在STA线程上创建一个对象,并封送指向另一个线程的指针,那么典型的情况是该对象仍将存在于原始STA线程上,并且调用将返回该线程,除非您采取特定步骤来指定其他方式。 (这里需要注意的事项:对象的线程模型是什么,以及它是否“聚合了自由线程编组器”。)

所以这不是一件坏事;但要确保你做得恰到好处。例如,您可能认为使用两个线程可能更有效;但后来发现,工作线程正在花费大量时间回调原始线程上的对象,使得性能比单线程情况更差。所以你需要先仔细考虑你的线程和对象策略。

(尽管如此,你可以根据需要调整尽可能多的线程,不要调用CoInitialize,只要它们不以任何方式使用COM或COM对象;如果需要那些线程因此,以某种方式与使用COM的线程进行通信,您可以使用您选择的任何“经典”IPC机制来管理该通信 - 例如,消息,全局等。)