COM元件中的執行緒模式 (轉)

worldblog發表於2007-12-07
COM元件中的執行緒模式 (轉)[@more@]

  COM中的執行緒
 lostall·com集中營

 提及COM的執行緒模式,實際上指的是兩個方面,一個是客戶的執行緒模式,一個是元件所支援的執行緒模式。客戶程式的執行緒模式只有兩種,單執行緒公寓(STA)和多執行緒公寓(MTA)。元件所支援的執行緒模式有四種:Single(單執行緒)、Apartment(STA)、Free(MTA)、Both(STA+MTA)。

  1、公寓只是個邏輯上的概念。一個STA只能包含一個執行緒,一個MTA可以包含多個執行緒。一個程式可以包含多個STA,但只能有一個MTA。MTA中各執行緒可以並行的本公寓內例項化的元件,而不需要進行排程。跨公寓呼叫元件例項必須要進行排程。(除非使用了自由執行緒排程器)

  2、客戶程式的執行緒是在呼叫CoInitializeEx()時決定客戶執行緒的型別的。如果以引數COINIT_APARTMENTTHREADED呼叫,則會建立一個STA公寓,客戶執行緒包含在這個公寓裡。如果以引數COINIT_MULTITHREADED呼叫,則建立一個MTA公寓,把執行緒加入到這個MTA中;如果程式內已經有了一個MTA,則不建立新的MTA,只把執行緒加入到已有的MTA。注意每個執行緒都必須呼叫CoInitializeEx()才能使用COM元件。

  3、執行緒最重要的是同步問題。STA是透過視窗訊息佇列來解決這個問題的。當客戶執行緒以COINIT_APARTMENTTHREADED呼叫CoInitializeEx()時,將為會該STA建立一個具有OleMainThreadWndClass視窗類的隱含視窗。所有對在這個公寓中建立的COM方法的呼叫都將都放到這個隱含視窗的訊息佇列中。所以每一個與STA相關聯的執行緒必須用GetMessage、DispatchMessage或類似方法來分派視窗訊息。MTA內各執行緒可並行呼叫同一個元件物件的例項,從而不保證性,所以實現同步訪問的責任就落在了元件身上。注意,S他的同步是公寓級的,就是說對公寓內不同元件的訪問都要放到同一個訊息佇列中,對一個例項的方法呼叫會影響對其他例項的呼叫,所以併發程度很低。

  4、在不同公寓間傳遞介面指標必須要經過排程。這主要還是為了同步對元件的呼叫。透過CoMarshalInterThreadInterfaceInStream和CoGetInterfaceAndReleaseStream實現。很簡單。

  5、Single型元件很特殊,它只能在一個單一的執行緒中。首先要說明的是一個程式中第一個以COINIT_APARTMENTTHREADED呼叫CoInitializeEx()的執行緒被稱作是主STA。每次用CoCreateInstance()建立的Single型元件實際上都是建立在了這個主STA中,而不管是誰呼叫了CoCreateInstance()這個。所有對這個Single元件方法的呼叫都必須要透過這個主STA。

  6、若STA建立STA型元件,是直接建立,直接呼叫。若STA建立MTA型元件,為元件建立一個MTA,STA透過訪問元件。若STA建立Both型元件,是直接建立,直接呼叫。若MTA建立STA型元件,系統為元件建立一個STA,MTA透過代理訪問元件。若MTA建立MTA型元件,是直接建立,直接呼叫。若MTA建立Both型元件,是直接建立,直接呼叫。可見如果客戶程式和元件都支援同樣的執行緒模式,那麼COM就允許客戶程式直接呼叫物件,這樣將產生最佳。

  7、Both型元件已經很好了,無論是STA還是MTA都可以直接建立呼叫它。但跨公寓的呼叫仍然要經過代理。為了更進一步以獲得最佳效能,可以使用自由執行緒排程器(FTM)。注意其它型別的元件也可以使用FTM,只是由Both使用FTM可獲得是最佳效果。FTM實現了介面IMarshal,當排程那兩個排程介面指標的函式時,這兩個函式(見5)內部呼叫IMarshal內的相關函式,並判斷如果排程發生在一個程式內的公寓之間則直接返回介面指標;如果排程發生在程式之間或者間,則呼叫標準的排程器,並返回指向代理物件的指標。所以可見使用FTM,即使是公寓之間也不用排程介面指標了!!

  8、FTM雖然好,但使用FTM的元件必須遵守某些限制:使用FTM的物件不能直接擁有沒有實現FTM的物件的介面指標;使用FTM的物件不能擁有其他公寓物件代理的引用。

  9、全域性介面表(GIT)。作用範圍是程式內。可以把介面指標存進表中,然後在別的公寓內把其取出,GIT自動執行公寓間的排程,所以很方便。GIT是透過IGlobalInterfaceTable訪問的。透過建立CLSID為CLSID_StdGlobalInterfaceTable的物件可呼叫它。


 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-989535/,如需轉載,請註明出處,否則將追究法律責任。

相關文章