?? 1.html
字號(hào):
<hr><br><A NAME="I510" ID="I510"></A><center><b><font size=+2>就緒線程管理部件的數(shù)據(jù)結(jié)構(gòu)及其實(shí)現(xiàn)</font></b></center><br>空閑處理機(jī)棧、處理機(jī)狀態(tài)數(shù)組<p> 在系統(tǒng)中設(shè)置一空閑處理機(jī)棧,所有空閑的處理機(jī)記錄在空閑處理機(jī)棧中,當(dāng)某一處理機(jī)空閑時(shí),把處理機(jī)號(hào)壓入棧中,如果有線程需要運(yùn)行,從棧中彈出一個(gè)處理機(jī)分配給線程使用。當(dāng)就緒線程堆非空時(shí),所有處理機(jī)都已分配給了線程,空閑處理機(jī)棧一定是空的。<br>在系統(tǒng)中設(shè)置一處理機(jī)狀態(tài)數(shù)組,每個(gè)處理機(jī)對(duì)應(yīng)數(shù)組中的一個(gè)元素。在數(shù)組中記錄著各個(gè)處理機(jī)需要切換的線程,在大多數(shù)情況下,當(dāng)前運(yùn)行的線程和需要切換的線程二者相同,表示不需要執(zhí)行處理機(jī)切換,如果二者不同,需要申請(qǐng)?zhí)幚頇C(jī)中斷,請(qǐng)求處理機(jī)執(zhí)行處理機(jī)切換,切換另一線程占用處理機(jī)。<br>運(yùn)行線程堆和就緒線程堆<br> 在虛擬地址基于文件的操作系統(tǒng)中,設(shè)置了兩個(gè)堆數(shù)據(jù)結(jié)構(gòu):運(yùn)行線程堆和就緒線程堆。所有正在處理機(jī)上運(yùn)行的線程記錄在運(yùn)行線程堆中;所有等待到處理機(jī)上去運(yùn)行的線程記錄在就緒線程堆中。運(yùn)行線程堆中線程的個(gè)數(shù)最多不超過(guò)系統(tǒng)支持的處理機(jī)數(shù)。<br>系統(tǒng)按照各個(gè)線程的優(yōu)先數(shù)對(duì)兩個(gè)堆實(shí)施管理。在就緒線程堆中,堆頂元素是優(yōu)先數(shù)最小優(yōu)先級(jí)最高的線程,如果需要選擇一個(gè)就緒線程占用處理機(jī),選擇堆頂元素對(duì)應(yīng)的線程;在運(yùn)行線程堆中,堆頂元素是優(yōu)先數(shù)最大優(yōu)先級(jí)最低的線程,如果需要選擇一個(gè)運(yùn)行線程放棄處理機(jī),也選擇堆頂元素對(duì)應(yīng)的線程。由于線程優(yōu)先數(shù)越小,優(yōu)先極越高,優(yōu)先數(shù)越大,優(yōu)先極越低,因此,運(yùn)行線程堆是一個(gè)最大化堆。<br> 由于系統(tǒng)選擇優(yōu)先級(jí)最高的線程占用處理機(jī)運(yùn)行,一般情況下,就緒線程堆堆頂元素對(duì)應(yīng)線程的優(yōu)先數(shù)大于運(yùn)行線程堆堆頂元素對(duì)應(yīng)線程的優(yōu)先數(shù)。如果由于某些原因線程的優(yōu)先數(shù)發(fā)生了變化(例如,線程改變了優(yōu)先數(shù)、處于運(yùn)行線程堆中線程睡眠、線程終止退出等),就緒線程堆堆頂元素對(duì)應(yīng)線程的優(yōu)先數(shù),可能小于運(yùn)行線程堆堆頂元素對(duì)應(yīng)線程的優(yōu)先數(shù),表示系統(tǒng)中某個(gè)處于就緒態(tài)線程的優(yōu)先級(jí)高于另一個(gè)處于運(yùn)行態(tài)線程的優(yōu)先級(jí),需要系統(tǒng)執(zhí)行處理機(jī)切換,使運(yùn)行線程堆堆頂元素對(duì)應(yīng)線程放棄處理機(jī),就緒線程堆堆頂元素對(duì)應(yīng)線程占用處理機(jī)。<p>向運(yùn)行線程堆或就緒線程堆插入線程的算法<p> 如果存在空閑處理機(jī),從空閑處理機(jī)棧彈出一個(gè)處理機(jī)號(hào)分配給線程,把分配的處理機(jī)號(hào)記錄在線程的控制塊中,在處理機(jī)狀態(tài)數(shù)組中記錄該處理機(jī)需要切換的線程,直接把線程加入到運(yùn)行線程堆中,并請(qǐng)求處理機(jī)執(zhí)行處理機(jī)切換。<br>如果不存在空閑處理機(jī),比較需要插入的線程優(yōu)先級(jí)和運(yùn)行線程堆堆頂元素對(duì)應(yīng)的線程的優(yōu)先級(jí),如果需要插入線程的優(yōu)先級(jí)不高于運(yùn)行線程堆堆頂元素對(duì)應(yīng)線程的優(yōu)先級(jí),直接把新創(chuàng)建的線程加入到就緒線程堆中。<br> 如果需要插入線程的優(yōu)先級(jí)高于運(yùn)行線程堆堆頂元素對(duì)應(yīng)線程的優(yōu)先級(jí),把需要插入的線程和運(yùn)行線程堆堆頂元素相互交換,對(duì)運(yùn)行線程堆執(zhí)行下移調(diào)整,把原運(yùn)行線程堆堆頂元素對(duì)應(yīng)的線程加入到就緒線程堆中;同時(shí),在處理機(jī)狀態(tài)數(shù)組中對(duì)應(yīng)處理機(jī)元素中,把需要切換線程域設(shè)置為新插入線程的線程標(biāo)識(shí)符,請(qǐng)求處理機(jī)執(zhí)行處理機(jī)切換。<p>從運(yùn)行線程堆或就緒線程堆刪除線程的算法<p> 如果線程處于就緒線程堆中,直接從就緒線程堆中刪除。<br> 如果線程處于運(yùn)行線程堆中,就緒線程堆非空,把刪除的線程和就緒線程堆堆頂元素對(duì)應(yīng)的線程執(zhí)行交換,對(duì)運(yùn)行線程堆執(zhí)行下移調(diào)整,再?gòu)木途w線程堆中把線程刪除;同時(shí),在處理機(jī)狀態(tài)數(shù)組對(duì)應(yīng)處理機(jī)的元素中,把需要切換線程域設(shè)置為原就緒線程堆堆頂元素對(duì)應(yīng)的線程,并請(qǐng)求處理機(jī)執(zhí)行處理機(jī)切換。<br> 如果線程處于運(yùn)行線程堆中,就緒線程堆為空,直接從運(yùn)行線程堆中刪除;同時(shí),在處理機(jī)狀態(tài)數(shù)組對(duì)應(yīng)處理機(jī)元素中,把需要切換線程域設(shè)置為空。把處理機(jī)號(hào)壓入空閑處理機(jī)棧中,并請(qǐng)求處理機(jī)執(zhí)行處理機(jī)切換,處理機(jī)切換為空閑狀態(tài)。<p><p><br><center><A HREF="#Content">[目錄](méi)</A></center><hr><br><A NAME="I511" ID="I511"></A><center><b><font size=+2>就緒線程管理部件提供的調(diào)用</font></b></center><br> 管理運(yùn)行線程堆和就緒線程堆的模塊統(tǒng)稱(chēng)為就緒線程管理部件,就緒線程管理部件為上層共提供了四個(gè)調(diào)用:<p> 向運(yùn)行線程堆或就緒線程堆中插入線程:線程對(duì)信號(hào)量執(zhí)行V操作時(shí),可能需要喚醒線程,調(diào)用本功能向運(yùn)行線程堆或就緒線程堆插入線程。<br> 從運(yùn)行線程堆或就緒線程堆刪除線程:線程對(duì)信號(hào)量執(zhí)行P操作時(shí),可能需要使線程睡眠,調(diào)用本功能從運(yùn)行線程堆或就緒線程堆刪除線程。<br> 線程優(yōu)先數(shù)調(diào)整:改變線程優(yōu)先數(shù)時(shí)調(diào)用本功能,首先從運(yùn)行線程堆或就緒線程堆刪除線程,修改線程優(yōu)先數(shù)后再插入到運(yùn)行線程堆或就緒線程堆中。<br> 處理機(jī)切換響應(yīng):處理機(jī)管理部件僅僅選擇哪些線程應(yīng)該在處理機(jī)上運(yùn)行,如果需要某個(gè)處理機(jī)執(zhí)行處理機(jī)切換,通過(guò)中斷網(wǎng)絡(luò)向處理機(jī)申請(qǐng)中斷,處理機(jī)響應(yīng)中斷,觸發(fā)中斷服務(wù)程序執(zhí)行處理機(jī)切換的操作,并調(diào)用本功能通知處理機(jī)管理部件已完成處理機(jī)切換。<p><p><p><center><A HREF="#Content">[目錄](méi)</A></center><hr><br><A NAME="I512" ID="I512"></A><center><b><font size=+2>信號(hào)量</font></b></center><br>內(nèi)核中信號(hào)量管理部件的實(shí)現(xiàn)<p> 信號(hào)量(semaphore)是E. W. Dijkstra在1965年提出的一種用于實(shí)現(xiàn)進(jìn)程之間同步和互斥的方法。一個(gè)信號(hào)量的值可以為0,表示沒(méi)有積累下來(lái)的喚醒操作,也沒(méi)有在信號(hào)量上睡眠的進(jìn)程;或者為正值,表示有一個(gè)或多個(gè)被積累下來(lái)的喚醒操作;或者為負(fù)值,其絕對(duì)值為在信號(hào)量上睡眠的進(jìn)程數(shù)。<br> 信號(hào)量管理部件提供四個(gè)功能調(diào)用:<br> ·申請(qǐng)一個(gè)信號(hào)量<br> ·釋放一個(gè)信號(hào)量<br> ·對(duì)信號(hào)量執(zhí)行P操作<br> ·對(duì)信號(hào)量執(zhí)行V操作<p><center><A HREF="#Content">[目錄](méi)</A></center><hr><br><A NAME="I513" ID="I513"></A><center><b><font size=+2>信號(hào)量和P、V操作</font></b></center><br> 對(duì)信號(hào)量存在兩種操作:對(duì)信號(hào)量的P操作和對(duì)信號(hào)量的V操作。<br> 對(duì)一信號(hào)量執(zhí)行P操作時(shí)檢查其值是否大于零。若是則將其值減1(用掉一個(gè)保存的喚醒信號(hào))并繼續(xù)執(zhí)行;若值小于等于零則將其值減1后睡眠,此時(shí)P操作并未結(jié)束。檢查數(shù)值、改變數(shù)值、以及可能發(fā)生的睡眠操作均作為一個(gè)單一的、不可分割的原子操作(atomic action)完成,即保證一旦一個(gè)信號(hào)量操作開(kāi)始,則在操作完成或阻塞之前別的進(jìn)程均不允許訪問(wèn)該信號(hào)量。這種原子性對(duì)于解決同步問(wèn)題和避免競(jìng)爭(zhēng)條件是非常重要的。<br> V操作遞增信號(hào)量的值。如果一個(gè)或多個(gè)進(jìn)程在該信號(hào)量上睡眠,無(wú)法完成一個(gè)先前的P操作,則由系統(tǒng)選擇其中的一個(gè)并允許其完成它的P操作,于是,對(duì)一個(gè)有進(jìn)程在其上睡眠的信號(hào)量執(zhí)行一次V操作之后,該信號(hào)量的值加1,在其上睡眠的進(jìn)程少了一個(gè)。遞增信號(hào)量的值和喚醒一個(gè)進(jìn)程同樣也是不可分割的。不會(huì)有進(jìn)程因執(zhí)行V而睡眠。<p><p><br><center><A HREF="#Content">[目錄](méi)</A></center><hr><br><A NAME="I514" ID="I514"></A><center><b><font size=+2>內(nèi)核中的信號(hào)量</font></b></center><br> 在LFYOS中,信號(hào)量是內(nèi)核維護(hù)的一種資源,應(yīng)用程序通過(guò)使用信號(hào)量實(shí)現(xiàn)線程之間的同步和互斥。<br> 線程可以通過(guò)內(nèi)核提供的調(diào)用申請(qǐng)和釋放信號(hào)量資源。申請(qǐng)信號(hào)量時(shí),用資源ID作調(diào)用的入口參數(shù)。如果兩個(gè)或多個(gè)線程使用相同的資源ID申請(qǐng)信號(hào)量,信號(hào)量管理部件保證它們申請(qǐng)到相同的信號(hào)量,以實(shí)現(xiàn)線程之間正確的同步和互斥。使用完信號(hào)量后應(yīng)釋放信號(hào)量資源,以便其它進(jìn)程使用。<br> LFYOS中信號(hào)量P、V操作的語(yǔ)義也和Dijkstra提出的信號(hào)量的語(yǔ)義有所不同。<br> 對(duì)于信號(hào)量V操作,線程可以指定遞增信號(hào)量的值,不僅僅可以實(shí)現(xiàn)對(duì)信號(hào)量值的加一操作,而且可以增加任意一個(gè)整數(shù);甚至可以指定喚醒所有睡眠在該信號(hào)量上的線程。信號(hào)量V操作的返回值為信號(hào)量的當(dāng)前值,通過(guò)指定遞增信號(hào)量的值為零,執(zhí)行信號(hào)量V操作可以查詢(xún)信號(hào)量的當(dāng)前值。線程還可以對(duì)某個(gè)線程而不是對(duì)信號(hào)量執(zhí)行V操作,由信號(hào)量管理部件對(duì)線程正在上面睡眠的信號(hào)量執(zhí)行V操作把線程喚醒。<br> 對(duì)于信號(hào)量P操作,如果信號(hào)量的當(dāng)前值小于等于0時(shí),線程可以選擇是睡眠還是直接返回;如果執(zhí)行P操作的線程睡眠,等到其它線程執(zhí)行了V操作后,執(zhí)行P操作的線程返回。P操作的返回值為一整數(shù)類(lèi)型的變量,如果其它線程執(zhí)行的V操作同時(shí)喚醒了多個(gè)線程,這些線程P操作的返回值從1開(kāi)始遞增排序,哪一個(gè)線程可以進(jìn)入臨界區(qū)由應(yīng)用程序確定。在LFYOS中,不僅線程自己可以執(zhí)行P操作,而且可以代替其它線程對(duì)某個(gè)信號(hào)量執(zhí)行P操作,從而使其它線程睡眠;再通過(guò)對(duì)信號(hào)量執(zhí)行V操作將其喚醒,因此,通過(guò)P、V操作可以實(shí)現(xiàn)對(duì)線程的調(diào)度和控制。<br> LFYOS中信號(hào)量和Dijkstra提出的信號(hào)量的另一點(diǎn)不同是:釋放信號(hào)量時(shí),如果存在線程睡眠在信號(hào)量上,這些線程被全部喚醒;而Dijkstra提出的信號(hào)量沒(méi)有釋放操作。<br> 如果執(zhí)行對(duì)信號(hào)量的V操作時(shí),指定喚醒所有睡眠在該信號(hào)量上的線程,P、V操作的語(yǔ)義類(lèi)似于UNIX內(nèi)核中的sleep()和wakeup()函數(shù)。<p><p><p><center><A HREF="#Content">[目錄](méi)</A></center><hr><br><A NAME="I515" ID="I515"></A><center><b><font size=+2>信號(hào)量管理數(shù)據(jù)結(jié)構(gòu)</font></b></center><br> 信號(hào)量管理數(shù)據(jù)結(jié)構(gòu)見(jiàn)后面的“數(shù)據(jù)結(jié)構(gòu)”部分,在系統(tǒng)中設(shè)置一信號(hào)量控制塊數(shù)組,每個(gè)信號(hào)量對(duì)應(yīng)著數(shù)組中的一個(gè)元素。<br> 信號(hào)量分成兩類(lèi):空閑信號(hào)量和已經(jīng)分配的信號(hào)量。所有空閑信號(hào)量鏈成一個(gè)單向鏈,用一個(gè)變量(空閑信號(hào)量鏈?zhǔn)祝┲赶蚩臻e信號(hào)量鏈,按先進(jìn)后出的棧式管理方式實(shí)施對(duì)空閑信號(hào)量的管理。<br> 線程由于對(duì)某個(gè)信號(hào)量執(zhí)行了P操作而睡眠,睡眠在某個(gè)信號(hào)量上的所有線程都已經(jīng)從就緒線程堆或運(yùn)行線程堆中刪除,并鏈成一個(gè)雙向的環(huán)鏈,鏈?zhǔn)字羔槺4嬖谛盘?hào)量控制塊數(shù)組中。執(zhí)行V操作時(shí)把睡眠的線程從線程環(huán)鏈中刪除,插入就緒線程堆或運(yùn)行線程堆中。<p><p><p><center><A HREF="#Content">[目錄](méi)</A></center><hr><br><A NAME="I516" ID="I516"></A><center><b><font size=+2>信號(hào)量管理的實(shí)現(xiàn)</font></b></center><br> 信號(hào)量管理包括四個(gè)對(duì)信號(hào)量操作的實(shí)現(xiàn):<br> ·申請(qǐng)一個(gè)信號(hào)量<br> ·釋放一個(gè)信號(hào)量<br> ·對(duì)信號(hào)量執(zhí)行P操作<br> ·對(duì)信號(hào)量執(zhí)行V操作<br> 執(zhí)行對(duì)信號(hào)量的P操作和V 操作以前,首先檢查信號(hào)量的狀態(tài),如果是一個(gè)沒(méi)有分配的信號(hào)量,不能對(duì)其執(zhí)行任何操作,信號(hào)量操作直接返回,否則根據(jù)不同的操作請(qǐng)求,進(jìn)行相應(yīng)的處理:<br> 執(zhí)行P操作時(shí),對(duì)信號(hào)量的值執(zhí)行減一操作,根據(jù)減一后信號(hào)量的值,分別處理:<br> 如果大于等于0,P操作直接返回,返回值為1。<br> 如果小于零,但是指定了P操作不睡眠,對(duì)信號(hào)量的值執(zhí)行加一操作后P操作返回,返回值為0。<br> 如果小于零,但是指定了P操作可以睡眠,把線程從運(yùn)行線程堆或就緒線程堆刪除,插入到信號(hào)量的睡眠線程環(huán)鏈中,使線程睡眠。當(dāng)線程被其它線程執(zhí)行的V操作喚醒時(shí),這些被喚醒線程的P操作返回,被V操作喚醒的各個(gè)線程的返回值從2開(kāi)始順序遞增。<br> 執(zhí)行對(duì)線程的V操作時(shí),首先根據(jù)線程確定的信號(hào)量并設(shè)置遞增信號(hào)量的值為1,然后設(shè)置一初始值為0的遞增計(jì)數(shù)器,根據(jù)指定的遞增信號(hào)量的值,循環(huán)重復(fù)執(zhí)行以下操作:<br> 對(duì)信號(hào)量的值和計(jì)數(shù)器的值執(zhí)行加一操作。<br> 如果在信號(hào)量的睡眠線程環(huán)鏈中存在睡眠的線程,喚醒環(huán)鏈上的第一個(gè)線程,把線程從信號(hào)量的睡眠線程環(huán)鏈中刪除,插入到運(yùn)行線程堆或就緒線程堆中,設(shè)置P操作的返回值為計(jì)數(shù)器的當(dāng)前值;其它情況不執(zhí)行線程喚醒操作。<br> 執(zhí)行申請(qǐng)信號(hào)量調(diào)用時(shí),從空閑信號(hào)量棧中取出一個(gè)信號(hào)量,執(zhí)行初始化操作后把信號(hào)量ID返回給應(yīng)用程序。<br> 執(zhí)行釋放信號(hào)量調(diào)用時(shí),如果信號(hào)量上存在睡眠線程,執(zhí)行V操作將其喚醒;然后把信號(hào)量插入空閑信號(hào)量棧中。<p><p><center><A HREF="#Content">[目錄](méi)</A></center><hr><br><A NAME="I517" ID="I517"></A><center><b><font size=+2>線程遷移</font></b></center><br>內(nèi)核中線程遷移部件的實(shí)現(xiàn)<p> 在LFYOS中,線程和進(jìn)程的關(guān)系是一種臨時(shí)性的關(guān)系,線程并非永久性地屬于某一個(gè)進(jìn)程,通過(guò)線程遷移調(diào)用一個(gè)線程可以從一個(gè)進(jìn)程進(jìn)入另一個(gè)進(jìn)程,執(zhí)行被調(diào)用進(jìn)程相應(yīng)的功能,在被調(diào)用進(jìn)程中執(zhí)行完畢后,通過(guò)線程返回調(diào)用線程退回到原進(jìn)程中運(yùn)行。通過(guò)線程遷移調(diào)用和線程返回調(diào)用,線程實(shí)現(xiàn)了在不同進(jìn)程之間的遷移。<br> 通過(guò)線程遷移調(diào)用,一個(gè)線程進(jìn)入另一個(gè)進(jìn)程時(shí),在新進(jìn)程中,只能從進(jìn)程初始執(zhí)行點(diǎn)開(kāi)始執(zhí)行。通過(guò)在進(jìn)程初始執(zhí)行點(diǎn)處放置一定的檢查程序,可以防止惡意的線程對(duì)進(jìn)程的破壞,保證線程調(diào)用的安全性。<br> 同樣,當(dāng)一個(gè)線程從一個(gè)進(jìn)程返回到原來(lái)的進(jìn)程時(shí),系統(tǒng)也要保證線程返回到正確的執(zhí)行點(diǎn),防止惡意的特洛伊木馬造成的破壞,為此,在線程控制塊中專(zhuān)門(mén)設(shè)置了線程返回控制塊棧。當(dāng)一個(gè)線程執(zhí)行線程遷移調(diào)用,從一個(gè)進(jìn)程進(jìn)入另一個(gè)進(jìn)程時(shí),系統(tǒng)保存線程返回調(diào)用時(shí)應(yīng)該恢復(fù)的返回地址、進(jìn)程標(biāo)識(shí)符等信息;當(dāng)線程執(zhí)行線程返回調(diào)用從一個(gè)進(jìn)程返回到原來(lái)的進(jìn)程時(shí),根據(jù)以前保存的線程返回地址,恢復(fù)線程在原進(jìn)程環(huán)境中的運(yùn)行。通過(guò)保存線程返回地址,防止服務(wù)進(jìn)程對(duì)調(diào)用進(jìn)程惡意的破壞,保證線程返回的安全性。<p>線程遷移部件提供的功能調(diào)用及實(shí)現(xiàn)<p> 線程遷移部件提供了兩個(gè)功能調(diào)用:線程遷移調(diào)用和線程返回調(diào)用。<br> 線程遷移部件分下面三步執(zhí)行線程遷移調(diào)用:<br> ·判斷目標(biāo)進(jìn)程是否是一個(gè)合法的進(jìn)程,如果非法直接返回出錯(cuò);否則繼續(xù)向下執(zhí)行。<br> ·如果需要把當(dāng)前應(yīng)該保存的信息壓入線程返回控制塊棧中,執(zhí)行壓棧操作,如果壓棧操作溢出,直接返回出錯(cuò)信息;如果不需要執(zhí)行壓棧操作或需要執(zhí)行壓棧操作且壓棧操作沒(méi)有溢出,繼續(xù)向下執(zhí)行。<br> ·最后把線程的當(dāng)前所屬進(jìn)程設(shè)置為目標(biāo)進(jìn)程,根據(jù)目標(biāo)進(jìn)程的初始執(zhí)行點(diǎn),在目標(biāo)進(jìn)程中開(kāi)始執(zhí)行。<p> 線程遷移部件分下面步執(zhí)行線程返回調(diào)用:<br> 從線程返回控制塊棧中彈出應(yīng)該恢復(fù)的信息。<br> 如果不能彈出應(yīng)該恢復(fù)的信息,線程終止,否則根據(jù)彈出的信息恢復(fù)線程在原進(jìn)程中的運(yùn)行。<p><p><p><center><A HREF="#Content">[目錄](méi)</A></center><hr><br><A NAME="I518" ID="I518"></A><center><b><font size=+2>中斷</font></b></center><br>中斷服務(wù)程序和處理機(jī)切換部件的實(shí)現(xiàn)<p> 中斷服務(wù)程序是
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -