COM套間和執行緒模型.

honwsn發表於2010-03-22

在看元件的登錄檔時,對TreadingModel很不理解,所以網上查閱總結了下。大部分內容摘自《理解 COM 套間》,謝謝原作者。

[@more@]


套間的提出是為了元件在多執行緒環境下安全執行,因為有跨執行緒呼叫同一個元件方法的狀況存在。若該元件介面是執行緒安全的,則無須套間,否則需要套間的協助,就如視窗過程函式一樣,
視窗過程本身並不是執行緒安全的,但是訊息佇列的機制,保證了視窗過程總是在一個執行緒中執行,序列地處理訊息。

Windows的訊息機制是透過視窗來實現的,那麼一個執行緒要接收訊息,也應該有一個視窗。
COM API的設計者在它們的API函式中實現了一個隱藏的視窗。在我們呼叫CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)的時候,會生成這個視窗。該視窗是隱藏的,有了這個視窗,就可以支援訊息機制,就有辦法來實現物件中函式的逐一執行。這樣當物件指標被傳到其它執行緒的時候,從外部呼叫該物件的方法的時候,就會先發一個訊息到原執行緒,
而不再直接訪問物件。

這樣設計的機制保證COM元件物件中的方法總是在一個執行緒中被呼叫(序列的),是執行緒安全的。

1.套間與執行緒
CoInitializeEx是一個建立套間的過程,
我們使用CoInitializeEx(NULL, COINIT_MULTITHREADED)後,會建立一個MTA套間。
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)建立個STA套間。
一個程式可以包含多個STA,但只能有一個MTA。 一個STA只能包含一個執行緒,一個MTA可以包含多個執行緒。

2.COM元件的執行緒模型(Threading Model)共有四種:Single Apartment Both Free
(可以透過修改登錄檔直接改變這個元件的Treading Model)

2.1 Single:
當一個元件的執行緒模型被標識為Single,說明程式中這個元件的例項 都必須在同一個套間執行緒中。(該套間執行緒就是程式建立的第一個STA套間執行緒)。
無論在程式中建立多少個元件例項,介面呼叫都是在同一個執行緒中完成的。這 其中當然涉及到給隱藏視窗傳送訊息和等待,需要注意的是避免執行緒間的死鎖問題。

2.2 Apartment:
當一個元件的執行緒模型被標識為Apartment,當建立了一個元件,並把元件的某個
介面傳遞給另一個執行緒時,在這個兩個執行緒中呼叫這個介面提供的方法,
最終都是在同一個執行緒中完成的。
說明該元件不是執行緒安全的,需要套間的協助。所處的套間執行緒必須是COINIT_APARTMENTTHREADED。
2.3 Free
說明元件是執行緒安全的,當發生2.2的狀況時,呼叫是在不同執行緒中完成的。但是所處
套間必須是MTA(COINIT_MULTITHREADED)

2.4 Both
說明元件是執行緒安全的,所處的套間MTA(COINIT_MULTITHREADED)
和STA(COINIT_APARTMENTTHREADED)都可以。

3.預設套間執行緒

當在建立元件時所處的執行緒(所建立的套間)與該元件的執行緒模型不匹配。這種狀況下
系統就會把元件物件放入預設的套間中(當然是執行在一個預設的執行緒中).

4.套間的本質

An apartment is neither a process nor a thread; however, apartments share some of the properties of both。
套間是儲存線上程的TLS中的一個資料結構,借用該結構使套間和執行緒之間建立起某種關係,
透過該結構可以幫助不同的套間之間透過訊息機制來實現函式的呼叫,以保證多執行緒環境下,資料的同步。

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

相關文章