www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > > 充電吧
[導(dǎo)讀]查找了好多資料,終于對套件這一概念有一點(diǎn)心得,趕緊記錄下來。首先,只要遵守COM規(guī)范,不用COM庫也能編寫COM程序,那相當(dāng)于自己實(shí)現(xiàn)用到的COM庫函數(shù)。本篇COM如果單獨(dú)出現(xiàn),指COM庫。1 ? 進(jìn)

查找了好多資料,終于對套件這一概念有一點(diǎn)心得,趕緊記錄下來。
首先,只要遵守COM規(guī)范,不用COM庫也能編寫COM程序,那相當(dāng)于自己實(shí)現(xiàn)用到的COM庫函數(shù)。本篇COM如果單獨(dú)出現(xiàn),指COM庫。
1 ? 進(jìn)程、線程回顧
《WINDOWS核心編程》對進(jìn)程和線程有深入解釋,一個程序運(yùn)行起來,需要一個進(jìn)程作為容器。進(jìn)程管理所有系統(tǒng)資源、內(nèi)存、線程等等。線程是CPU的調(diào)度單位,有自己的棧和寄存器狀態(tài)。程序最初創(chuàng)建的線程叫主線程,主線程可以創(chuàng)建子線程,子線程還可以創(chuàng)建子線程。
不同進(jìn)程之間是無法直接通信的,因為它們在虛擬內(nèi)存中的地址不一樣。但操作系統(tǒng)通過LPC機(jī)制,可以完成不同進(jìn)程之間的通信。
?
COM在進(jìn)程間通信的方法是本地過程調(diào)用(LPC),因為操作系統(tǒng)知道各個進(jìn)程的確切邏輯地址,所以操作系統(tǒng)可以完成這一點(diǎn)。不同進(jìn)程間傳遞的參數(shù)需要調(diào)整,LPC技術(shù)可以完成普通數(shù)據(jù)的直接拷貝(甚至包括自定義類和指針),但對于接口參數(shù),COM實(shí)現(xiàn)了IMarshal接口以調(diào)整。
為了可以用同樣的方式和進(jìn)程外、遠(yuǎn)程組件通信,客戶端不直接和組件通信,而是和代理/存根通信,代理/存根是(而且必須是) DLL形式,能完成參數(shù)調(diào)整和LPC調(diào)用。代理存根不用自己寫,系統(tǒng)會自動產(chǎn)生。
注:接口的調(diào)整,包括列集和散集兩種marshal/unmarshal。
2 ? COM線程模型
2.1 分清模型與實(shí)現(xiàn)
?? ?看過《Inside C++ Object Model》(中文名:深入C++對象模型;侯捷譯)的人都知道,C++對象模型有三種,各家編譯器都選擇其中效率最高的一種實(shí)現(xiàn)出來。另外兩種就留在了理論世界,實(shí)現(xiàn)出來沒有太大意義。提這個的原因,就是為了弄清楚這一點(diǎn):COM線程模型只是理論構(gòu)想,是一種抽象的數(shù)學(xué)模型,還要COM庫通過各種手段實(shí)現(xiàn)出來,才能為我們使用。
2.2 套間的由來
最開始的COM庫,支持的使用組件的唯一模式是single-thread-per-process模式。這樣就避免了多線程的同步,而且組件執(zhí)行的線程肯定是創(chuàng)建它的線程。
然而組件對象真正的執(zhí)行環(huán)境很復(fù)雜。COM組件的執(zhí)行環(huán)境有兩種:單線程環(huán)境Single-Thread,多線程環(huán)境Multi-Thread。單線程要考慮執(zhí)行線程是否是創(chuàng)建組件的線程;多線程還要考慮并發(fā)、同步、死鎖、競爭等問題。無論哪種環(huán)境,都要編寫大量的代碼以使COM組件對象正確的運(yùn)行。
為了使程序員減輕痛苦,COM庫決心提供一套機(jī)制來幫助程序員。如果我們都遵從這套機(jī)制,只要付出較少的勞動,就可以讓組件對象和COM庫一起完成工作。COM庫這套機(jī)制的核心技術(shù)就是“套間技術(shù)”。
2.3 COM的多線程模型
2.3.1 COM庫的規(guī)定
關(guān)于多線程問題方面,COM庫做出了如下規(guī)則(不是COM標(biāo)準(zhǔn),是COM庫為了簡化多線程編程中對組件的調(diào)用而制定的):
1. ?COM庫提供兩種套間,單線程套間和多線程套間,COM組件的編寫者最好提供對應(yīng)的屬性(后面會提到),COM組件的使用者要在套間里創(chuàng)建和調(diào)用組件。
2. ?COM庫對所有的調(diào)用進(jìn)行參數(shù)調(diào)整(如果需要),不管是對進(jìn)程內(nèi)服務(wù)器的調(diào)用,還是對進(jìn)程外服務(wù)器的調(diào)用。
3. ?線程內(nèi)調(diào)用、跨線程調(diào)用、跨進(jìn)程調(diào)用都用統(tǒng)一的方式。需要用代理的會用代理。
?
如此COM規(guī)定了COM庫、組件編寫者、組件使用者三方合作關(guān)系。COM庫進(jìn)行協(xié)調(diào)關(guān)系,會根據(jù)組件的能力,在不同環(huán)境(套間)中創(chuàng)建和調(diào)用組件;編寫者要說明組件可以生存的環(huán)境;調(diào)用者查詢接口,合理調(diào)用。
2.3.2 單線程套間STA
Single-threaded Apartments,一個套間只關(guān)聯(lián)一個線程,COM庫保證對象只能由這個線程訪問(通過對象的接口指針調(diào)用其方法),其他線程不得直接訪問這個對象(可以間接訪問,但最終還是由這個線程訪問)。
COM庫實(shí)現(xiàn)了所有調(diào)用的同步,因為只有關(guān)聯(lián)線程能訪問COM對象。如果有N個調(diào)用同時并發(fā),N-1個調(diào)用處于阻塞狀態(tài)。對象的狀態(tài)(也就是對象的成員變量的值)肯定是正確變化的,不會出現(xiàn)線程訪問沖突而導(dǎo)致對象狀態(tài)錯誤。
注意:這只是要求、希望、協(xié)議,實(shí)際是否做到是由COM決定的。這個模型很像Windows提供的窗口消息運(yùn)行機(jī)制,因此這個線程模型非常適合于擁有界面的組件,像ActiveX控件、OLE文檔服務(wù)器等,都應(yīng)該使用STA的套間。
2.3.3 多線程套間MTA
Multithreaded Apartments,一個套間可以對應(yīng)多個線程,COM對象可以被多個線程并發(fā)訪問。所以這個對象的作者必須在自己的代碼中實(shí)現(xiàn)線程保護(hù)、同步工作,保證可以正確改變自己的狀態(tài)。
這對于作為業(yè)務(wù)邏輯組件或干后臺服務(wù)的組件非常適合。因為作為一個分布式的服務(wù)器,同一時間可能有幾千條服務(wù)請求到達(dá),如果排隊進(jìn)行調(diào)用,那么將是不能想象的。
注意:這也只是一個要求、希望、協(xié)議而已。
2.3.4 COM+新增NA
COM+為了進(jìn)一步簡化多線程編程,引入了中立線程套間概念。
NA/TNA/NTA,Neutral Apartment/Thread Neutral Apartment / Neutral Threaded Apartment。這種套間只和對象相關(guān)聯(lián),沒有關(guān)聯(lián)的線程,因此任何線程都可以直接訪問里面的對象,不存在STA的還是MTA的。
2.4 到底什么是套間
根據(jù)《COM技術(shù)內(nèi)幕》的觀點(diǎn),COM沒有定義自己新的線程模型,而是直接利用了Win32線程,或者說對其做了改造、包裝。線程間的同步也是直接用的Win32 APIs。
《COM本質(zhì)論》設(shè)這樣定義的:套間定義了一組對象的邏輯組合,這些對象共享一組并發(fā)性和沖入限制。每個COM對象都屬于某一個套間,一個套間可以包含多個COM對象。
MSDN上解釋說,可以把進(jìn)程中的組件對象想象為分成了很多組,每一組就是一個套間。屬于這個套間的線程,可以直接調(diào)用組件,不屬于這個套間的線程,要通過代理才能調(diào)用組件。
最直接的說,COM庫為了實(shí)現(xiàn)簡化多線程編程的構(gòu)想,提出了套間概念。套間是一個邏輯上的概念,它把Win32里的線程、組件等,按照一定的規(guī)則結(jié)合在一起,并且以此提供了一種模式,用于多線程并發(fā)訪問COM組件方面。可以把套間看作COM對象的管理者,它通過調(diào)度,切換COM對象的執(zhí)行環(huán)境,保證COM對象的多線程調(diào)用正常運(yùn)行。COM和線程不是包含關(guān)系,而是對應(yīng)和關(guān)聯(lián)關(guān)系。
3 ? 第一方COM庫:模型的實(shí)現(xiàn)
3.1 單線程套間STA
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);這句代碼創(chuàng)建了一個STA,然后套間把當(dāng)前的線程和自己關(guān)聯(lián)在一起,線程被標(biāo)記為套間線程,只有這個線程能直接調(diào)用COM對象。
在創(chuàng)建套間的時候,COM創(chuàng)建了一個隱藏的窗口。關(guān)聯(lián)線程對組件的調(diào)用直接通過接口指針調(diào)用方法;其他線程對套間里的對象的調(diào)用,都轉(zhuǎn)變成對那個隱藏窗口發(fā)送消息,然后由這個隱藏窗口的消息處理函數(shù)來實(shí)際調(diào)用組件對象的方法。編寫組件代碼的時候,只需調(diào)用DispatchMessage即可將方法調(diào)用的消息和普通的消息區(qū)分開來(通過隱藏窗口的消息處理函數(shù))。
由于窗口消息的處理是異步的,所以所有的調(diào)用都是依次進(jìn)行的,不必考慮同步的問題。只要調(diào)用的時候,參數(shù)進(jìn)行合理調(diào)整即可(COM庫會做到這一點(diǎn))。但是對于全局變量和靜態(tài)變量,組件編寫者還是要費(fèi)心的。
?
一個STA只關(guān)聯(lián)一個線程, single-thread-per-process模式只是STA的一個特例。使用這種模式的線程叫套間線程(Apartment Thread)。
3.2 多線程套間MTA
CoInitializeEx(NULL, COINIT_MULTITHREADED);第一次如此調(diào)用的時候,會創(chuàng)建一個MTA,然后套間把當(dāng)前線程和自己關(guān)聯(lián)在一起,線程被標(biāo)記為自由線程。以后第二個線程再調(diào)用(在同一進(jìn)程中)的時候,這個MTA會把第二個線程也關(guān)聯(lián)在一起,并標(biāo)記為自由線程。一個MTA可以關(guān)聯(lián)多個線程。
所有的關(guān)聯(lián)線程都可以調(diào)用套間中的組件。這就涉及到同步問題,需要組件編寫者解決。
一個MTA可以關(guān)聯(lián)一個或多個線程,這種模式下,COM組件自己要考慮同步問題。使用這種模式的這些線程叫做自由線程(Free Thread) 。
3.3 總結(jié)
一個進(jìn)程可以有0個、1個或多個STA,還可以有0個或1個MTA。 同時使用CoInitialize(NULL)和CoInitializeEx(NULL,COINIT_APARTMENTTHREADED)是一樣的,也就是說,我們在使用CoInitialize的時候默認(rèn)的是使用套間線程?
一個線程,進(jìn)入(或創(chuàng)建)套間后,不能改變套間模式;但可以退出套間,然后以另外的模式再進(jìn)入(或創(chuàng)建)另一個套間。
?
在一個進(jìn)程中,主套間是第一個被初始化的。在單線程的進(jìn)程里,這是唯一的套間。調(diào)用參數(shù)在套間之間被調(diào)整,COM庫通過消息機(jī)制處理同步。
如果你設(shè)計多個線程作為自由線程,所有的自由線程在同一個單獨(dú)的套間中,參數(shù)被直接(不被列集)傳遞給這個套間的任何線程,而且你要處理所有的同步。
在既有自由線程又有套間線程的進(jìn)程里,所有自由線程在一個套間里,而其他套間都是單線程套間。而進(jìn)程是包含一個多線程套間和N個單線程套間的容器。
?
COM的線程模型為客戶端和服務(wù)器提供了這樣一種機(jī)制:讓不同的線程協(xié)同工作。不同進(jìn)程內(nèi),不同線程之間的對象調(diào)用也是被支持的。以調(diào)用者的角度來看,所有對進(jìn)程外對象的調(diào)用都是一致的,而不管它在怎樣的線程模型。以被調(diào)用者的角度來看,不管調(diào)用者的線程模型如何,所獲得的調(diào)用都是一致的。
?
客戶端和進(jìn)程外對象之間的交互也很直接,即使它們使用了不同的線程模型,因為它們屬于不同的進(jìn)程。COM介入了客戶端和服務(wù)器之間,通過標(biāo)準(zhǔn)的列集和RPC,并提供了跨線程操作的代碼。
4 ? 第二方COM組件的調(diào)用者
4.1 各種調(diào)用
4.1.1 同一線程中的調(diào)用
同步問題:不需要,調(diào)用者和組件在同一線程中,自然同步。
調(diào)整問題:不需要,COM庫不需要任何介入,參數(shù)也不需要調(diào)整,組件也不必線程安全。
調(diào)用地點(diǎn):當(dāng)前線程
這是最簡單的情況。
4.1.2 套間線程之間的調(diào)用
同步問題:COM庫對調(diào)用進(jìn)行同步。
調(diào)整問題:不管兩個套間是否在同一進(jìn)程,都需要調(diào)整。某些情況下,需要手動調(diào)整。
調(diào)用地點(diǎn): 對象所在套間線程。
4.1.3 自由線程之間的調(diào)用
同步問題:COM不進(jìn)行同步,組件自己同步。
調(diào)整問題:同一進(jìn)程不調(diào)整,不同進(jìn)程要調(diào)整。
調(diào)用地點(diǎn):客戶線程。
4.1.4 自由線程調(diào)用套間線程的組件
同步問題:COM庫對調(diào)用進(jìn)行同步。
調(diào)整問題:不管兩個套間是否在同一進(jìn)程,都需要調(diào)整。某些情況下,需要手動調(diào)整。
調(diào)用地點(diǎn):套間線程
4.1.5 套間線程調(diào)用自由線程的組件
同步問題:COM不進(jìn)行同步,組件自己同步。
調(diào)整問題:需要調(diào)整,同一進(jìn)程,COM會優(yōu)化調(diào)整。
調(diào)用地點(diǎn):客戶線程。
4.2 手工調(diào)整
如果通過COM方法,所有的參數(shù)都由COM庫進(jìn)行調(diào)整。有時候需要程序員手工對接口指針進(jìn)行列集marshal和散集unmarshal,那就是在跨越套間邊界,但沒有通過COM庫進(jìn)行通信的時候。更明確的說,不通過COM接口函數(shù),通過我們自己寫的函數(shù)跨套間傳遞接口指針的時候。
?
情況一:跨套間傳遞接口指針。
情況二:類廠在另外的套間中,創(chuàng)建類實(shí)例,并傳回給客戶端的接口指針。
?
列集函數(shù):CoMarshalInterThreadInterfaceInStream
散集函數(shù):CoGetInterfaceAndReleaseStream?
5 ? 第三方COM組件的編寫者
組件將在哪種類型的套間中執(zhí)行,是編寫者決定的。對于進(jìn)程外組件,要調(diào)用CoInitializeEx并指定參數(shù),以顯示確定套間類型。對于進(jìn)程內(nèi)的服務(wù)器來說,因為客戶端已經(jīng)調(diào)用CoInitializeEx產(chǎn)生套間了,為了允許進(jìn)程內(nèi)的服務(wù)器可以控制它們的套間類型,COM允許每個組件有自己不同的線程模型,并記錄在注冊表中。
HKEY_CLASSES_ROOT/CLSID/.../InprocServer32 鍵值ThreadingModel
5.1 線程模型屬性
組件編寫者可以實(shí)現(xiàn):同一個組件,既可以在STA中運(yùn)行,也可以在MTA中運(yùn)行,還可以在兩中環(huán)境中同時存在??梢哉f組件有一種屬性說明可以在哪種環(huán)境中生存,屬性名叫做“線程模型”(相當(dāng)于“隱藏”)也未嘗不可。COM+里真正引入了這個屬性,并叫做ThreadModel。這個屬性可以有如下取值:
1. ?Main Thread Apartment
2. ?Single Thread Apartment (Apartment)
3. ?Free Thread Apartment (Free)
4. ?Any Apartment (Both)
5. ?Neutral Apartment (N/A)
5.2 對象在哪個套間創(chuàng)建
下表中第一列為套間種類,第一行為對象線程模型屬性。那么,結(jié)果就是在這樣的套間中創(chuàng)建這樣的組件,組件在什么地方。在必要的時候,會創(chuàng)建一個代理,就是表中的宿主。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動電源

在工業(yè)自動化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動力設(shè)備,其驅(qū)動電源的性能直接關(guān)系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護(hù)是驅(qū)動電源設(shè)計中至關(guān)重要的兩個環(huán)節(jié),集成化方案的設(shè)計成為提升電機(jī)驅(qū)動性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動電源

LED 驅(qū)動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動電源易損壞的問題卻十分常見,不僅增加了維護(hù)成本,還影響了用戶體驗。要解決這一問題,需從設(shè)計、生...

關(guān)鍵字: 驅(qū)動電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動電源的公式,電感內(nèi)電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計 驅(qū)動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動汽車的核心技術(shù)之一是電機(jī)驅(qū)動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動汽車的動力性能和...

關(guān)鍵字: 電動汽車 新能源 驅(qū)動電源

在現(xiàn)代城市建設(shè)中,街道及停車場照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動電源 LED

LED通用照明設(shè)計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動電源

關(guān)鍵字: LED 驅(qū)動電源 開關(guān)電源

LED驅(qū)動電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動電源
關(guān)閉