張 蕊
天津師范大學(xué)計(jì)算機(jī)與信息工程學(xué)院,天津 300387
對(duì)并行計(jì)算的研究是當(dāng)代高效計(jì)算機(jī)系統(tǒng)設(shè)計(jì)中至關(guān)重要的一部分,并行的效果往往依賴于支持并行性的系統(tǒng)所提供的并發(fā)機(jī)制。進(jìn)程是計(jì)算機(jī)資源分配的單位。一個(gè)大任務(wù)一般可以分成多個(gè)子任務(wù), 這些子任務(wù)的執(zhí)行組成了整個(gè)任務(wù)功能。線程和進(jìn)程的區(qū)別主要存在于創(chuàng)建線程的階段, 線程相較于進(jìn)程并不是復(fù)制父進(jìn)程映象, 而是和父進(jìn)程一起實(shí)現(xiàn)共享。多個(gè)線程一起共享各種資源和同一地址空間, 不同的只有代碼段和私有棧。因此創(chuàng)建線程和調(diào)度線程的費(fèi)用與原來的方式相比明顯降低了。
所謂線程(thread),簡(jiǎn)單地說就是指進(jìn)程中的單一順序控制流(a thread is a single stream of execution with in a process)。線程是程序的一個(gè)調(diào)度單位,同時(shí)也是計(jì)算機(jī)科學(xué)領(lǐng)域的術(shù)語之一。線程的另一個(gè)別稱是輕量級(jí)進(jìn)程(lightweight processes)。線程往往有自己的寄存器集、局部線程變量、棧、線程說明數(shù)據(jù)、程序計(jì)數(shù)器、狀態(tài)信息以及線程說明信號(hào)掩碼。一個(gè)進(jìn)程里的多個(gè)線程之間往往要共享同樣的的地址空間并共同構(gòu)成一個(gè)大的進(jìn)程,線程執(zhí)行的基礎(chǔ)是要先有進(jìn)程的執(zhí)行,也就是說線程其實(shí)是無法獨(dú)立執(zhí)行的。
多線程是從硬件或軟件上實(shí)現(xiàn)多個(gè)線程并發(fā)執(zhí)行的一種技術(shù)。有多線程能力的計(jì)算機(jī)往往具有強(qiáng)大的硬件支持,因而能夠同時(shí)運(yùn)行多于一個(gè)的線程,進(jìn)而提升了整體處理的效能。引進(jìn)多線程具有一定的必要性,因?yàn)槎嗑€程具有諸多優(yōu)點(diǎn)。多線程可以提高系統(tǒng)的吞吐率和程序的響應(yīng)效率,同時(shí)有助于改善程序的結(jié)構(gòu),從而使用戶能夠更加有效地利用好系統(tǒng)的資源。此外,多線程在降低資源的占用和加強(qiáng)用戶間通信效果等諸多方面也有積極的作用。例如,我們?cè)趙ord 中打印文件的過程,對(duì)文件的編輯并不會(huì)影響到對(duì)文件的打印,編輯操作和打印操作其實(shí)是異步執(zhí)行的,或者可以理解為打印操作是在后臺(tái)完成的。這是因?yàn)橄到y(tǒng)創(chuàng)建了兩個(gè)獨(dú)立線程來分別完成對(duì)文件的編輯和對(duì)文件的打印,同時(shí)規(guī)定負(fù)責(zé)編輯文檔的線程的優(yōu)先級(jí)要高于負(fù)責(zé)打印文檔的線程。在我們實(shí)際的應(yīng)用中,多線程的方法非常適合用于解決多個(gè)獨(dú)立任務(wù)組成的問題。
用戶級(jí)線程(user level threads)是由用戶程序來負(fù)責(zé)管理的,傳統(tǒng)的操作系統(tǒng)內(nèi)核只負(fù)責(zé)對(duì)進(jìn)程的管理。
操作系統(tǒng)通常會(huì)提供一個(gè)能夠在用戶空間里執(zhí)行的線程庫,以方便用戶程序?qū)τ谟脩艏?jí)線程的管理工作。這個(gè)能夠在用戶空間里執(zhí)行的線程庫提供了包括線程的創(chuàng)建、線程的調(diào)度、線程的執(zhí)行、線程的撤銷、線程間通信以及存儲(chǔ)上下文在內(nèi)的一些功能。有了線程庫提供的這些功能,用戶級(jí)線程的實(shí)現(xiàn)就不再需要操作系統(tǒng)給予其他的特殊支持了。此外,對(duì)于操作系統(tǒng)分配的用戶堆棧和用戶寄存器,用戶級(jí)進(jìn)程只能使用其所屬進(jìn)程被分配的用戶堆棧和用戶寄存器。
用戶級(jí)線程的上下文切換與內(nèi)核無關(guān),所以可能存在相關(guān)進(jìn)程的狀態(tài)是阻塞或等待的,而屬于該進(jìn)程的線程狀態(tài)卻是執(zhí)行情況。
核心及線程與用戶級(jí)線程的不同之處在于,前者不僅可以在同一個(gè)處理機(jī)上被并發(fā)執(zhí)行,還可以在不同處理機(jī)上被并行執(zhí)行。所以操作系統(tǒng)內(nèi)核在負(fù)責(zé)同一進(jìn)程內(nèi)部的不同線程的調(diào)度工作的同時(shí),可能也要進(jìn)行不同進(jìn)程之間的調(diào)度工作。這種工作機(jī)制有效地避免線程處于執(zhí)行狀態(tài)、進(jìn)程處于等待或阻塞狀態(tài)的情況發(fā)生。而另外,為了達(dá)到提高操作系統(tǒng)內(nèi)核程序執(zhí)行效率的效果,核心級(jí)線程技術(shù)也會(huì)用于內(nèi)核程序自身。綜上,和用戶級(jí)線程進(jìn)行比較,核心級(jí)線程在上下文切換上所用的時(shí)間要大于用戶級(jí)線程。
在JAVA 語言中,可采用兩種方式產(chǎn)生線程。第一種方法是繼承,即通過繼承Thread 類的方法,重寫和覆蓋部分方法run(),然后即可創(chuàng)建和啟用自己定義的線程實(shí)例,當(dāng)然這些線程實(shí)例是在應(yīng)用程序類里創(chuàng)建和啟動(dòng)的。另一種方法是實(shí)現(xiàn)Runnable 接口。這種方法也是目前是非常常用的創(chuàng)建線程的方法之一,它打破了第一種方法(即繼承Thread 類)受到的的限制。在JAVA 的類庫里,Runnable 接口中僅僅包含了一個(gè)run()方法。所有對(duì)象,只要屬于能夠?qū)崿F(xiàn)該接口的類,就應(yīng)該可以用線程的方式執(zhí)行。當(dāng)然,只是對(duì)類進(jìn)行聲明是無法對(duì)任何對(duì)線程提供支持的,因此還需要對(duì)Thread 類實(shí)例進(jìn)行創(chuàng)建。
JAVA 對(duì)多線程同步控制的方法主要是圍繞關(guān)鍵字synchronized 展開,并配合wait、sleep、notify 等方法,來實(shí)現(xiàn)類似操作系統(tǒng)中PV 原語的信號(hào)量機(jī)制。因此將JAVA 對(duì)多線程的同步控制步驟歸納如下:
1) 對(duì)需要同步保護(hù)的幾個(gè)方法或代碼段增加synchronized 限制符,這就是加鎖的過程;
2)對(duì)增加了synchronized 限制符的方法或代碼中配合使用wait、sleep 等阻塞方法,來實(shí)現(xiàn)需要的功能;
3)在增加了synchronized 限制符的代碼或方法最后用notif 或notifyall 等方法喚醒阻塞中的線程,實(shí)現(xiàn)線程間的通信。
目前,對(duì)計(jì)算機(jī)中多線程問題的研究主要應(yīng)用于局域網(wǎng)服務(wù)器中的文件管理或通信控制、WWW 服務(wù)器的多線程并發(fā)研究?jī)蓚€(gè)方面。在局域網(wǎng)服務(wù)器的文件管理中,服務(wù)器進(jìn)程會(huì)派生出相應(yīng)的線程來處理用戶訪問文件的要求。為了能夠應(yīng)對(duì)同時(shí)接受到多個(gè)訪問文件要求的情況,操作系統(tǒng)可以采取派生出多個(gè)線程的方法進(jìn)行處理。當(dāng)計(jì)算機(jī)的系統(tǒng)是多處理的情況下,線程還能在不同處理機(jī)上被執(zhí)行。www 服務(wù)器分為重復(fù)服務(wù)器和并發(fā)服務(wù)器。重復(fù)服務(wù)器一般面向能在短時(shí)間內(nèi)處理完成的請(qǐng)求, 并且是由服務(wù)器來對(duì)這些請(qǐng)求進(jìn)行處理的。并發(fā)服務(wù)器則面向那些處理完成時(shí)間不定長(zhǎng)的請(qǐng)求, 由服務(wù)器的進(jìn)程或線程來處理每個(gè)請(qǐng)求。
[1]張玉蓉,藍(lán)雯飛.Java的多線程技術(shù)探討[J].計(jì)算機(jī)教育,2006(4).
[2]http://uule.iteye.com/blog/1106710.