[微軟技術白皮書] 這個秋天最熱門的是自由執行緒模型(Free Threading Model) |
|
axsoft
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:681 回覆:1056 積分:969 註冊:2002-03-13 發送簡訊給我 |
來源:http://www.microsoft.com/taiwan/msdn/
目前微軟已移除此文章! David Platt
David Platt 是 Rolling Thunder Computing 的總裁及創辦人 (www.rollthunder.com)。他也是 The Essence of OLE with ActiveX (Prentice Hall, 1996) 的作者。可以與 David 聯絡用 dplatt@rollthunder.com. 在多執行緒程式上面使用 COM 是一個充滿了害怕,不確定性,及懷疑的主題。如果您正在寫一個 COM 物件,您需要擔心關於對物件的成員函數及資料的連續存取嗎?物件伺服器的全域函數及資料變成如何了呢?而撰寫一個使用 COM 的用戶端應用程式又變成如何呢--應用程式可以從兩個執行緒存取同一個物件嗎?可以從同一個伺服器的兩個不同的執行緒存取兩個不同的物件嗎?又如果一個物件的表現方式從一個版本到另一個版本有所變更的時候呢? 請不要擔心。在大多數 COM 的主題中,事實並不像預測的那麼痛苦。如果您遵循一些簡單的規則,COM 將會處理好令人害怕的細節部分。 要求一個用戶對其想要使用的物件的內部有詳細的認識,或讓一個物件要顧慮到其用戶端的的內部,將會跟所有 COM 的基本原則有所衝突。COM 的 C 代表元件--若一個用戶端需要顧慮一個物件的內部,那麼這個物件不能真正稱為元件。COM 支援在任何一邊都不需要知道或顧慮另一邊在作什麼的方式執行緒。其遵循以下的原則運作: 用戶端應用程式在其經由 CoInitializeEx 函數初始化 COM 之時告訴 COM 其在使用執行緒之時所要遵循的規則,取代 CoInitialize。 物件的伺服器告訴 COM 其在使用執行緒之時要遵循的規則,不論當其呼叫CoInitializeEx 用於一個EXE 伺服器或經由製作登錄內容用於一個 DLL 伺服器。 當一個用戶端建立一個物件之時,COM 會比較每方面所宣稱其遵循的執行緒規則。如果各分面都保證經由相同的規則進行,那麼 COM 會在兩者之間設定一個直接的連接並且不干涉。如果他們遵循不同的規則,那麼 COM 會設定在兩方之間安排使得每方面都只看到其宣稱其知道如何處裡的執行緒規則。後面這個情況會耗費一些執行效能但是可以讓所有遵循不相同執行緒規則的各方面可以一起運作而不會有抱怨聲或需要一個特殊的方式。
執行緒模組選項
我知道有更多潛在的 COM 程式設計師被和所有其他視窗的術語不同的專業術語 "執行緒模型," "apartment 執行緒," 及 "自由執行緒" 給嚇退了。雖然無法改變的術語持續在變更,他們並沒有那麼糟。 一個執行緒模型是一組規則的集合用來描述一個物件或用戶端所遵循用於執行緒及 COM 之間的互動行為。我之前的文章,"Give ActiveX?-based Web Pages a Boost with the Apartment Threading Model," (MSJ,Febuary 1997),已經解釋過 apartment 執行緒模型,也就是所謂的單一執行緒 apartment 模型,一組可以被遵循的規則。這篇文章承續了 1997 年二月那篇文章所沒有提到的部分,所以如果您剛接觸到在 COM 之下執行緒的爭議的話,我強烈建議您從閱讀那篇文章開始。其可以在四月發行的 Microsoft Developer Network 光碟片中取得,或您可以訂閱 MSJ 過期的刊物經由他們的網站站台 (http://www.microsoft.com/msj)。 在 apartment 模型中,最主要的規則就是一個用戶端應用程式只能使用建立物件的執行緒呼叫一個物件的方法。這表示同一個伺服器的不同物件可以被不同的執行緒呼叫,但是每個物件只會被從一個執行緒呼叫。這個照順序表示物件必須將其對其伺服器的全域變數及函數作序列化的存取,但是對其本身的 instance 資料則不會如此。在 apartment 模型之下,物件相對地更容易寫作,但是用戶端可能更難處理。如果一個 apartment 執行緒用戶端需要從一個不同的執行緒呼叫一個物件的方法,他可以這樣做,但是其必須要跳過一些環節並且要先和作業系統協調。 這篇文章描述自由執行緒模型,也就是所謂的多執行緒 apartment 模型,這是另外一組物件或伺服器可能選擇遵循的規則。在自由執行緒模型中,一個用戶端應用程式可能會在任何時間從任何執行緒呼叫任何物件方法或 COM 函數。這端視物件序列存取到所有需要用來進來的呼叫會不會衝突。其提供最大的執行效能及彈性。代價是相對於 apartment 模型物件這些物件本身更難撰寫,雖然自由執行緒的用戶端應用程式比 apartment 執行緒的用戶端應用程式簡單。 使用自由執行緒模型比 apartment 模型要好的地方在哪裡?它是好在當有一個物件需要被從超過一個以上的執行緒存取時。假設您經由 DCOM 將一個用戶端應用程式連接到一個遠端的機器。當遠端用戶端呼叫那個物件的一個方法,伺服器會從一個為這個目的存在的集區中的一個現存的執行緒接收那個呼叫。這個接收執行緒使得本機的呼叫到真實的物件。如果物件支援自由執行緒模型,那麼就可以直接從接收執行緒中呼叫到物件裡面。如果物件支援 apartment 模型,那麼這個呼叫會被傳送到物件原來建立的執行的執行緒並且結果會在傳回到用戶端之前先傳送到接收執行緒。您引起您所不需要的額外處理花費。您也承擔物件正在服務其他物件的風險或--更糟的是--被在等待某些同步事件所阻擋。最後,您無法利用伺服器有多重中央處理器晶片的狀況,這變的越來越常見。 在另外一個範例中,假設您有一個單一物件代表一個到資料庫的連接,或可能是一個硬體的一部份。這個文章引用的範例程式模擬後面的狀況。假設您有四個或五個需要存取那個物件的執行緒。在 apartment 執行緒模型之下,物件可能置於,至多,這些執行緒其中之一。其他執行緒可能需要在起始的時候設立用來從他們本身的執行緒存取這個物件的執行緒間的處理代理人。您將會引發程式碼必須在起始的時候設立排列以及排列的耗費於每次您做呼叫的時候所得到的損失。如果物件及用戶端都支援自由執行緒模型,那麼多重執行緒全部可以直接連接到物件,而不用排列。物件本身需要將其本身的呼叫序列化到他們需要的範圍,而您會引發這個耗費,但是物件的程式設計師的對其表現方式的豐富知識使他可以將這個狀況加以最佳化。大多數時候,許多這個呼叫可能會是重複進入並且不需要將全部序列化。您真正必須要將常地序列化的可以比 COM 的通用排列器更便宜地完成。
自由執行緒用戶端應用程式
自由執行緒用戶端應用程式比 apartment 用戶端容易撰寫。一個 apartment 執行緒用戶端必須遵循每些有限制的規則關於哪些執行緒是被允許存取這些物件的。一個自由執行緒容器全部所需要 做的是製作一個到 API 函數 ConInitializeEx 的呼叫,傳送一個 COINIT_MULTITHREADED 的數值作為其第二個參數如圖 1 所示。不像 apartment 模型一樣,每個個別的執行緒不需要呼叫 CoInitializeEx;一個呼叫處理這個程序中的所有執行緒。這將 COM 在用戶端應用程式的位址空間起始化並且告訴他這個應用程式支援自由執行緒模型。一旦其這樣做之後,用戶端應用程式可能接著會在任何時間從任何執行緒呼叫任何 COM 函數或物件方法。 // constant _WIN32_DCOM 定義於計畫的設定項
在t WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, 在t nCmdShow)
{
/*
檢查 CoCreateInstanceEx() 函示是否存在於作業
系統 DLL Ole32.dll 中。如果沒有發現,那麼就是沒有支援自由執行緒模型。通知使用者並且離開。
*/
HANDLE hMod = GetModuleHandle ("ole32.dll") ;
FARPROC fp = GetProcAddress (hMod, "CoCreateInstanceEx") ;
if (fp == NULL)
{
MessageBox (NULL, "This version of the operating system does not\
support the free threading model", "Error", MB_OK) ;
return -1 ;
}
/*
將 COM 初始化用於自由執行緒模型。
*/
CoInitializeEx (NULL, COINIT_MULTITHREADED) ;
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |