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

多線程應用程序可為每個對象分配一條線程或固定數(shù)量的線程,當新對象創(chuàng)建時循環(huán)使用它們。作為一個緩沖的線程池管理程序,可以利用它為客戶端應用程序維護打開的自動化服務器實例。在這種方案中,如果客戶端應用程序需要使用某個對象,它們需要向緩沖池管理程序請求使用一個線程。緩沖池管理程序?qū)z查緩沖池,并決定是否準許請求。這種方法具有以下優(yōu)點:
(1)它避免了每個客戶端請求帶來的大量自動化服務器創(chuàng)建費用。因為緩沖池通常是在客戶端需要服務器之前就創(chuàng)建完畢的。
(2)根據(jù)客戶端請求的頻率、潛在的客戶端的個數(shù)以及服務器任務所需的時間,創(chuàng)建的緩沖池的大小比一對一的客戶/服務器分配方案通常要小得多(而且緩沖池的大小是可以隨時進行調(diào)整的)。如果緩沖池的大小為 5 個線程,那么在通常情況下是能夠滿足 60 個客戶端的需求的。
(3)它限制特定類型的服務器不得超出規(guī)定的個數(shù),該閾值是由服務器管理員確定的。這是一種非常有用的性能調(diào)節(jié)參數(shù),它還可以防止服務器被請求高峰的低優(yōu)先級服務器濫用。
自動化服務器可以作為客戶端運行在同一臺計算機上。它也可以在遠程計算機上運行,從而得到分布式處理帶來的強大處理能力以及共享的網(wǎng)絡服務器帶來的多用戶訪問特性。
由于服務器遠程應用程序不具有通常意義上的用戶界面,那么提供狀態(tài)監(jiān)控的另一種方法是由服務器提供狀態(tài)方法,并由單獨的監(jiān)控程序來對服務器的狀態(tài)進行查詢。
需要注意的一點是,由于關于線程的函數(shù)VB5本身并沒有提供,必須借助于Win95系統(tǒng)提供的API應用程序接口函數(shù)集,這些函數(shù)必須先定義后使用。使用中也需要注意它們的參數(shù)傳遞問題,由于這些函數(shù)大部分是為C++程序員設計的,其中就涉及到一些參數(shù)類型轉(zhuǎn)換的技巧??梢哉f,API接口為VB提供了最寶貴的高級功能的基礎,在很多VB自身沒有解決方案的情況下,調(diào)用API接口函數(shù)往往幾乎是唯一的可選方法。
四、結束語
VB5通過自身特有的“單元模型”多線程模式為程序員們提供了創(chuàng)建多線程組件的功能。通過多線程技術在VB5中的應用,為企業(yè)級應用,尤其是在遠程應用程序及客戶機/服務器的分布式處理方面,提供了強大多任務處理能力以及共享網(wǎng)絡服務器帶來的多用戶訪問特性。為多任務的大型應用程序提供了一種優(yōu)化的解決思路和方法。
參考文獻:
1 美 Stefano Maruzzi 《The Microsoft Windows 95 Developer’s Guide》
北京:機械工業(yè)出版社 1997.1
2 美 Dan Appleman 著《 Dan Appleman’s Visual Basic 5.0 Programmer’s Guide to the Win32 API 》 北京:機械工業(yè)出版社 1998.8
3 美 Chapman.D 著《Web Development with Visual Basic 5.0》
北京:機械工業(yè)出版社 1998.6
4 美 Mckelvy,M等 著《Special Edition Using Visual Basic 5》
北京:機械工業(yè)出版社 1997.12