摘要:多線程技術(shù)是Win95系統(tǒng)的一大特色。本文深入闡述了Win95進(jìn)程的多線程機(jī)制,并詳細(xì)討論了在VB5中實(shí)現(xiàn)多線程并行性多任務(wù)的方法。
關(guān)鍵詞 Win95 VB5 多線程 進(jìn)程 多任務(wù) API
VB5作為應(yīng)用程序的強(qiáng)大開(kāi)發(fā)平臺(tái),其新增的支持多線程組件的功能為大型企業(yè)和遠(yuǎn)程應(yīng)用提供了堅(jiān)實(shí)的基礎(chǔ)和廣闊的應(yīng)用前景。通過(guò)多線程組件技術(shù)來(lái)優(yōu)化遠(yuǎn)程服務(wù)和客戶機(jī)/服務(wù)器應(yīng)用程序已經(jīng)成為一種重要的應(yīng)用程序優(yōu)化方案。
一、Win95系統(tǒng)的多線程機(jī)制及其與WIN 3.x多任務(wù)機(jī)制的比較
支持基于多線程(Multi-thread)的多任務(wù)處理是Win95系統(tǒng)比16位的Windows3.x單純劃分CPU時(shí)間的多任務(wù)處理優(yōu)越的重要標(biāo)志之一。它的預(yù)先搶占式多任務(wù)和多線程處理使Win95系統(tǒng)的響應(yīng)和平穩(wěn)的后臺(tái)處理性能得到很好的改善。
Windows 3.x操作系統(tǒng)實(shí)現(xiàn)的多任務(wù)被稱作協(xié)作式多任務(wù)。協(xié)作式多任務(wù)的關(guān)鍵是每個(gè)單獨(dú)的應(yīng)用程序決定何時(shí)放棄處理器以讓另外一個(gè)可能正在等待處理的應(yīng)用程序?qū)崿F(xiàn)處理。這使得Windows 3.x平臺(tái)易受到不完善的應(yīng)用程序的影響,這種應(yīng)用程序會(huì)在實(shí)現(xiàn)一些漫長(zhǎng)費(fèi)時(shí)的處理或干脆陷入死循環(huán)中讓其他應(yīng)用程序也被困住而不能運(yùn)行。另外,在Windows 3.x中,所有應(yīng)用程序都是單線程的,即在運(yùn)行時(shí)的每個(gè)時(shí)間點(diǎn)上只有一條執(zhí)行路徑。Windows 3.x的這種單線程協(xié)作式多任務(wù)機(jī)制顯然在相當(dāng)多的時(shí)候只能提供一種低效率和不夠安全穩(wěn)定的多任務(wù)運(yùn)行環(huán)境。
對(duì)于32位Windows 95,操作系統(tǒng)在本質(zhì)上發(fā)生了變化。由預(yù)先搶占式多任務(wù)代替了協(xié)作式多任務(wù)。所謂預(yù)先搶占式多任務(wù)就是由操作系統(tǒng)而不是應(yīng)用程序自身來(lái)決定何時(shí)把處理器從當(dāng)前的應(yīng)用程序撤出,并把處理器交給另一個(gè)正在等待處理器的應(yīng)用程序來(lái)使用。這與當(dāng)時(shí)擁有處理器的應(yīng)用程序是否準(zhǔn)備放棄處理器給另外的應(yīng)用程序使用無(wú)關(guān),處理器不必經(jīng)過(guò)應(yīng)用程序的同意就被操作系統(tǒng)奪走了。這樣操作系統(tǒng)才能使多個(gè)操作大數(shù)量任務(wù)的應(yīng)用程序在每個(gè)任務(wù)上取得大致相同的進(jìn)展。操作系統(tǒng)的這一手段阻止了某個(gè)應(yīng)用程序在私占處理器時(shí)使其他應(yīng)用程序難以執(zhí)行的可能性。
一個(gè)Win95的32位應(yīng)用程序總是由一個(gè)進(jìn)程、一個(gè)主線程和若干個(gè)子線程組成,它的一個(gè)突出特點(diǎn)是支持多線程,即在競(jìng)爭(zhēng)CPU的線程分配CPU時(shí)間。進(jìn)程(Process)是一個(gè)運(yùn)行例程,當(dāng)一個(gè)應(yīng)用程序調(diào)入內(nèi)存準(zhǔn)備執(zhí)行時(shí),它就產(chǎn)生一個(gè)進(jìn)程。一個(gè)進(jìn)程由若干EXE文件的代碼和數(shù)據(jù)塊組成,它們被存放在邏輯上達(dá)4GB的線性地址空間內(nèi),EXE所需的DLL(動(dòng)態(tài)鏈接庫(kù))也將它們的代碼和數(shù)據(jù)裝入到此空間內(nèi)。進(jìn)程是靜態(tài)的,即一個(gè)32位的Win95進(jìn)程并不執(zhí)行什么指令,為了讓進(jìn)程完成一些工作,進(jìn)程必須至少占有一個(gè)線程,由線程負(fù)責(zé)執(zhí)行包含在進(jìn)程的地址空間中的代碼。進(jìn)程占有的資源(包括其內(nèi)的線程)都隨著進(jìn)程的生成而產(chǎn)生,都隨著進(jìn)程的終止而被系統(tǒng)撤消。
線程(Thread)是進(jìn)程中的一個(gè)執(zhí)行單元。同一進(jìn)程的各個(gè)線程對(duì)應(yīng)于一組CPU指令、一組CPU寄存器以及一個(gè)堆棧。進(jìn)程空間存放的代碼由線程來(lái)執(zhí)行,每個(gè)進(jìn)程中至少有一個(gè)線程在執(zhí)行其地址空間中的代碼。對(duì)于同一進(jìn)程中的多個(gè)線程來(lái)說(shuō),它們可以共享地址空間和所有的處理器資源,包括線程存取令牌、基本優(yōu)先級(jí)、對(duì)象句柄和其他資源等。同時(shí),線程的執(zhí)行與否,是看其處在掛起態(tài)還是激活態(tài)。處于激活態(tài)的各線程由調(diào)度程序決定哪個(gè)線程將得到下一個(gè)處理器時(shí)間片。下一個(gè)時(shí)間片總屬于那些準(zhǔn)備執(zhí)行的線程中優(yōu)先權(quán)最高的一個(gè)。
在Win95中,存取不可共享的資源、代碼段稱為臨界區(qū)。需要注意的是,為保證代碼的正確執(zhí)行,每次只能有一個(gè)線程在臨界區(qū)段中執(zhí)行。在一個(gè)線程正在向一個(gè)文件寫(xiě)入數(shù)據(jù)、更新數(shù)據(jù)庫(kù)或修改可共享的變量時(shí),其他線程不允許存取同一資源。另外由于Win95為每個(gè)進(jìn)程創(chuàng)建2GB的進(jìn)程空間,操作系統(tǒng)DLL和其他DLL被裝入其上的2GB地址空間中,這樣每個(gè)進(jìn)程都有自己的存儲(chǔ)空間的拷貝。這種臨界區(qū)和2GB地址空間的設(shè)置都大大提高了Win95多任務(wù)環(huán)境下的安全性和穩(wěn)定性。
允許有多個(gè)應(yīng)用程序同時(shí)運(yùn)行的能力,也就具有了對(duì)單個(gè)應(yīng)用程序,在任何時(shí)刻都有多道線程在執(zhí)行的技術(shù)。線程對(duì)應(yīng)用程序來(lái)說(shuō)就像應(yīng)用程序?qū)Σ僮飨到y(tǒng)一樣。如果某個(gè)應(yīng)用程序有多道線程在運(yùn)行,基本上就有多個(gè)“應(yīng)用程序”在整個(gè)應(yīng)用程序中運(yùn)行。這就允許應(yīng)用程序同時(shí)完成多項(xiàng)工作。
基于線程的多任務(wù)系統(tǒng),使得同一進(jìn)程的兩個(gè)或多個(gè)線程可以同時(shí)運(yùn)行。對(duì)用戶而言,多任務(wù)的優(yōu)點(diǎn)是能夠同時(shí)打開(kāi)和運(yùn)行多個(gè)應(yīng)用程序。對(duì)應(yīng)用程序開(kāi)發(fā)者來(lái)說(shuō),Win95多任務(wù)的優(yōu)點(diǎn)是能夠創(chuàng)建多線程的應(yīng)用程序以及執(zhí)行多線程的進(jìn)程,這樣就便于各任務(wù)之間的協(xié)調(diào)操作和運(yùn)行。例如,可以將整個(gè)進(jìn)程劃分為接受用戶輸入的線程、數(shù)據(jù)處理線程、接受遠(yuǎn)程信息線程、外圍處理線程等,這樣使得每個(gè)線程都同時(shí)運(yùn)行,充分利用了CPU的空閑時(shí)間片,使得進(jìn)程(應(yīng)用程序)的整體運(yùn)行效率得到較大提高。
另外,線程僅需要很少的附加資源開(kāi)銷,并且線程的創(chuàng)建比進(jìn)程快。用多線程實(shí)現(xiàn)并行性多任務(wù),避免了用多個(gè)進(jìn)程(即多個(gè)應(yīng)用程序)實(shí)現(xiàn)并行性的缺陷。同時(shí),由于同一進(jìn)程的所有線程共享同一內(nèi)存(這些線程僅具有不同的堆棧和寄存器內(nèi)容),故不再需要特殊的數(shù)據(jù)傳送機(jī)制。顯然,多個(gè)線程在相互通信時(shí),完全不需要建立共享存儲(chǔ)區(qū)或共享文件。
正是線程的低資源開(kāi)銷和高的運(yùn)行效率,使得它相對(duì)于進(jìn)程式并行性多任務(wù)具有更大的優(yōu)勢(shì)和更為廣闊的應(yīng)用前景。多線程技術(shù)在遠(yuǎn)程應(yīng)用和客戶機(jī)/服務(wù)器方式的應(yīng)用中占據(jù)著舉足輕重的地位。
二、VB5中的多線程技術(shù)
Win95中的多線程是一種標(biāo)準(zhǔn)模式,它得到了VC++或BC++等開(kāi)發(fā)工具的很好支持。但是它的工作原理和編程機(jī)制卻是一種針對(duì)純C++程序員的專利。對(duì)VB這種舍棄了指針等復(fù)雜數(shù)據(jù)類型的以簡(jiǎn)便和實(shí)用見(jiàn)長(zhǎng)的開(kāi)發(fā)工具卻并不完全適合。
在VB5中能多線程運(yùn)行的應(yīng)用程序必須滿足以下的條件-即這個(gè)應(yīng)用程序必須放棄用戶交互,即不能有類似于窗口之類的用戶界面。因而,微軟在VB5中實(shí)際上不允許創(chuàng)建這種復(fù)雜的標(biāo)準(zhǔn)多線程應(yīng)用程序。
但是VB5為了遠(yuǎn)程應(yīng)用程序和客戶機(jī)/服務(wù)器的分布式處理的考慮,允許通過(guò)一種稱為“單元模型”(apartment-model)的多線程模式來(lái)創(chuàng)建多線程組件(如ActiveX EXE)。在這種模式中線程的同步問(wèn)題通過(guò)給每個(gè)線程一套組件的全局變量并完全除去全局資源(如窗體)來(lái)避免。用單元模型線程,每個(gè)線程都有各自要使用或訪問(wèn)的內(nèi)存對(duì)象及對(duì)象變量的拷貝。即每個(gè)線程都有自己的單元,單元里放著線程要使用的對(duì)象,線程就被限制在自己的單元里。這樣就把程序員從不得不考慮線程間協(xié)調(diào)使用變量和資源的難題中解脫出來(lái)??梢?jiàn),VB5在增加線程功能的同時(shí),也簡(jiǎn)化了內(nèi)存對(duì)象的管理和線程同步。
從以上可以得出這樣一個(gè)結(jié)論,即應(yīng)用VB5來(lái)獲取多線程效果是實(shí)際可行的,只要?jiǎng)?chuàng)建一個(gè)進(jìn)程外的ActiveX服務(wù)器,并使用ActiveX的自動(dòng)控制功能來(lái)為它工作就可以了。
可見(jiàn),VB5應(yīng)用程序和DLL中的線程與通常形式的多線程方式不同,VB5中的線程特性使得它區(qū)別于支持標(biāo)準(zhǔn)多線程處理的VC++或BC++開(kāi)發(fā)工具。
三、VB5的多線程應(yīng)用與編程
在分布式處理或遠(yuǎn)程自動(dòng)化的客戶機(jī)/服務(wù)器方式的應(yīng)用中,為提高系統(tǒng)的效率經(jīng)常需要優(yōu)化程序。以一個(gè)遠(yuǎn)程應(yīng)用程序?yàn)槔?,如果客戶?qǐng)求的遠(yuǎn)程對(duì)象是多任務(wù)而且遠(yuǎn)程應(yīng)用程序已在服務(wù)器上運(yùn)行,那么在創(chuàng)建對(duì)象時(shí)客戶應(yīng)用程序響應(yīng)最快。然而,遠(yuǎn)程應(yīng)用程序中的多任務(wù)對(duì)象會(huì)為客戶導(dǎo)致問(wèn)題。例如,如果多個(gè)客戶同時(shí)使用一個(gè)遠(yuǎn)程應(yīng)用程序,其中一個(gè)客戶觸發(fā)了內(nèi)部錯(cuò)誤,使遠(yuǎn)程應(yīng)用程序異常退出,那么其他客戶使用的對(duì)象也被清除。類似地,占用應(yīng)用程序的操作也會(huì)給多任務(wù)對(duì)象客戶導(dǎo)致問(wèn)題:所有客戶都必須等待每一個(gè)操作完成。當(dāng)遠(yuǎn)程應(yīng)用程序同時(shí)為多個(gè)客戶程序服務(wù)時(shí),這個(gè)問(wèn)題就十分突出,將顯著降低系統(tǒng)的性能。
由于VB5支持多線程的組件技術(shù),可以用多線程來(lái)優(yōu)化多任務(wù)對(duì)象的性能。在多線程下,每個(gè)新的多任務(wù)對(duì)象都獨(dú)立運(yùn)行-即單個(gè)客戶不能占用其他客戶的遠(yuǎn)程應(yīng)用程序。
在實(shí)際創(chuàng)建多線程的多任務(wù)對(duì)象時(shí)有一個(gè)很大的限制-即應(yīng)用程序不能包含窗體。這意味著應(yīng)用程序無(wú)法與用戶交互。但是可以通過(guò)用多線程應(yīng)用程序發(fā)放單用途應(yīng)用程序?qū)ο蟮倪\(yùn)行實(shí)例來(lái)解決這個(gè)問(wèn)題,在VB5中,這種類型的多線程應(yīng)用程序稱為線程池管理器。
在中文VB5中建立一個(gè)多線程的應(yīng)用程序的基本步驟如下:
(1) 從“工程”菜單中選擇項(xiàng)目“工程1屬性”。
(2) 在“工程屬性”對(duì)話框中選擇“ActiveX EXE”工程類型,“啟動(dòng)對(duì)象”下拉框中選擇“無(wú)”,此時(shí)“執(zhí)行無(wú)用戶界面”的復(fù)選框有效,選中它。
(3) 在“線程緩沖池”項(xiàng)中選擇于包含的線程數(shù)。
(4) 加入程序運(yùn)行需要的功能代碼。
(5) 編譯此項(xiàng)目。4
編譯時(shí)的工程屬性設(shè)置具體如下圖。
多線程應(yīng)用程序可為每個(gè)對(duì)象分配一條線程或固定數(shù)量的線程,當(dāng)新對(duì)象創(chuàng)建時(shí)循環(huán)使用它們。作為一個(gè)緩沖的線程池管理程序,可以利用它為客戶端應(yīng)用程序維護(hù)打開(kāi)的自動(dòng)化服務(wù)器實(shí)例。在這種方案中,如果客戶端應(yīng)用程序需要使用某個(gè)對(duì)象,它們需要向緩沖池管理程序請(qǐng)求使用一個(gè)線程。緩沖池管理程序?qū)z查緩沖池,并決定是否準(zhǔn)許請(qǐng)求。這種方法具有以下優(yōu)點(diǎn):
(1)它避免了每個(gè)客戶端請(qǐng)求帶來(lái)的大量自動(dòng)化服務(wù)器創(chuàng)建費(fèi)用。因?yàn)榫彌_池通常是在客戶端需要服務(wù)器之前就創(chuàng)建完畢的。
(2)根據(jù)客戶端請(qǐng)求的頻率、潛在的客戶端的個(gè)數(shù)以及服務(wù)器任務(wù)所需的時(shí)間,創(chuàng)建的緩沖池的大小比一對(duì)一的客戶/服務(wù)器分配方案通常要小得多(而且緩沖池的大小是可以隨時(shí)進(jìn)行調(diào)整的)。如果緩沖池的大小為 5 個(gè)線程,那么在通常情況下是能夠滿足 60 個(gè)客戶端的需求的。
(3)它限制特定類型的服務(wù)器不得超出規(guī)定的個(gè)數(shù),該閾值是由服務(wù)器管理員確定的。這是一種非常有用的性能調(diào)節(jié)參數(shù),它還可以防止服務(wù)器被請(qǐng)求高峰的低優(yōu)先級(jí)服務(wù)器濫用。
自動(dòng)化服務(wù)器可以作為客戶端運(yùn)行在同一臺(tái)計(jì)算機(jī)上。它也可以在遠(yuǎn)程計(jì)算機(jī)上運(yùn)行,從而得到分布式處理帶來(lái)的強(qiáng)大處理能力以及共享的網(wǎng)絡(luò)服務(wù)器帶來(lái)的多用戶訪問(wèn)特性。
由于服務(wù)器遠(yuǎn)程應(yīng)用程序不具有通常意義上的用戶界面,那么提供狀態(tài)監(jiān)控的另一種方法是由服務(wù)器提供狀態(tài)方法,并由單獨(dú)的監(jiān)控程序來(lái)對(duì)服務(wù)器的狀態(tài)進(jìn)行查詢。
需要注意的一點(diǎn)是,由于關(guān)于線程的函數(shù)VB5本身并沒(méi)有提供,必須借助于Win95系統(tǒng)提供的API應(yīng)用程序接口函數(shù)集,這些函數(shù)必須先定義后使用。使用中也需要注意它們的參數(shù)傳遞問(wèn)題,由于這些函數(shù)大部分是為C++程序員設(shè)計(jì)的,其中就涉及到一些參數(shù)類型轉(zhuǎn)換的技巧。可以說(shuō),API接口為VB提供了最寶貴的高級(jí)功能的基礎(chǔ),在很多VB自身沒(méi)有解決方案的情況下,調(diào)用API接口函數(shù)往往幾乎是唯一的可選方法。
四、結(jié)束語(yǔ)
VB5通過(guò)自身特有的“單元模型”多線程模式為程序員們提供了創(chuàng)建多線程組件的功能。通過(guò)多線程技術(shù)在VB5中的應(yīng)用,為企業(yè)級(jí)應(yīng)用,尤其是在遠(yuǎn)程應(yīng)用程序及客戶機(jī)/服務(wù)器的分布式處理方面,提供了強(qiáng)大多任務(wù)處理能力以及共享網(wǎng)絡(luò)服務(wù)器帶來(lái)的多用戶訪問(wèn)特性。為多任務(wù)的大型應(yīng)用程序提供了一種優(yōu)化的解決思路和方法。
參考文獻(xiàn):
1 美 Stefano Maruzzi 《The Microsoft Windows 95 Developer’s Guide》
北京:機(jī)械工業(yè)出版社 1997.1
2 美 Dan Appleman 著《 Dan Appleman’s Visual Basic 5.0 Programmer’s Guide to the Win32 API 》 北京:機(jī)械工業(yè)出版社 1998.8
3 美 Chapman.D 著《Web Development with Visual Basic 5.0》
北京:機(jī)械工業(yè)出版社 1998.6
4 美 Mckelvy,M等 著《Special Edition Using Visual Basic 5》
北京:機(jī)械工業(yè)出版社 1997.12