微软的Aparment类比(STA,MTA):需要帮助理解它

时间:2012-01-26 06:48:33

标签: multithreading com sta mta

我已经阅读了很多关于微软线程公寓模型的内容,但我仍然在查看它时遇到一些麻烦。

微软使用生活在公寓里的生物的类比。所以,对于STA,请考虑以下内容(我知道这有点傻)。

  1. 假设thread = person和COMObject =细菌。这个人住在公寓里,细菌就住在这个人里面。所以在STA-Land中,一个线程存在于STA中,而COMObject存在于线程内部,因此为了与COMObject交互,必须通过在COMObject的线程上运行代码来实现。

  2. 假设thread = person和COMObject = cat。这个人住在公寓里,猫和这个人一起住在公寓里。在STA-Land中,线程和COMObject处于同一层级。

  3. Q1。上面哪个类比是正确的,或者如果两者都不正确,您将如何描述STA?

    Q2。你会如何描述MTA?

2 个答案:

答案 0 :(得分:3)

我不喜欢这些类比。他们很困惑。

你创建了一个公寓。

如果它是一个STA,公寓里只会有一个线程,所以该公寓中的所有对象都将在该单个线程上执行(因此该公寓中的对象没有并发执行)

如果它是MTA,则该公寓中可以有多个线程。因此,如果需要,MTA中的对象需要显式实现同步。

物体住在一个公寓里。同一个公寓里可以有多个物品。

A very good read here

答案 1 :(得分:3)

这不是一个好词。它实际上描述了线程行为。一个线程告诉COM它在CoInitializeEx()调用中的行为,在STA和MTA之间进行选择。通过使用STA,线程承诺它的行为方式适合非线程安全的代码。它所作出的坚定承诺是:

  • 永不阻止执行
  • 抽取消息循环

使用MTA意味着一个线程可以做任何想做的事情,并且不会努力支持非线程安全的代码。

首先创建COM对象时这很重要。这样的对象在注册表中包含一个键,用于描述它实现的线程安全性。 ThreadingModel键。到目前为止,此密钥的最常见值是“Apartment”(或缺失),告诉COM它根本不支持线程,并且对象的任何调用都必须来自同一个线程。

如果创建这样一个对象的线程在STA中,那么一切都很愉快。毕竟,该线程承诺支持单线程对象。如果线程在MTA中然后出现问题,则线程表示它不支持线程安全但仍然创建了一个非线程安全的对象。 COM中的COM步骤创建一个 new 线程,一个可以支持非线程安全代码的STA线程。代码获取对象的代理。对该对象进行的任何调用都通过该代理进行。代理代码拦截调用并使其在创建的STA线程上运行,从而确保以线程安全的方式进行调用。

你可以想象,代理完成的工作并不便宜。它涉及两个线程上下文切换,并且必须从函数参数构造堆栈帧以进行调用。它还必须等到线程准备好执行调用。这称为 marshaling ,它比不必编组的调用慢3个数量级。这或许也解释了STA线程具有上面列出的这两个要求的原因。它无法阻止,因为只要它阻止了无法进行编组调用并且很可能造成死锁。并且它必须提供一个消息循环,该循环使得将调用注入另一个线程的可能性。

因此,让线程加入MTA很容易为您编程。但致命的表现。 STA 高效