杭電計(jì)算機(jī)操作系統(tǒng)課程設(shè)計(jì)指導(dǎo)書(shū)_第1頁(yè)
杭電計(jì)算機(jī)操作系統(tǒng)課程設(shè)計(jì)指導(dǎo)書(shū)_第2頁(yè)
杭電計(jì)算機(jī)操作系統(tǒng)課程設(shè)計(jì)指導(dǎo)書(shū)_第3頁(yè)
杭電計(jì)算機(jī)操作系統(tǒng)課程設(shè)計(jì)指導(dǎo)書(shū)_第4頁(yè)
杭電計(jì)算機(jī)操作系統(tǒng)課程設(shè)計(jì)指導(dǎo)書(shū)_第5頁(yè)
已閱讀5頁(yè),還剩123頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

操作系統(tǒng)課程設(shè)計(jì)指導(dǎo)書(shū)

趙偉華梁紅兵劉真

2015年9月

計(jì)算機(jī)學(xué)院

目錄

第一章操作系統(tǒng)課程設(shè)計(jì)的內(nèi)容與實(shí)施方法-3-

1.1操作系統(tǒng)課程設(shè)計(jì)總體要求-3-

1.2操作系統(tǒng)課程設(shè)計(jì)的內(nèi)容-3-

1.3操作系統(tǒng)課程設(shè)計(jì)實(shí)施方案-4-

第二章基于DOS的多任務(wù)系統(tǒng)的實(shí)現(xiàn)-5-

2.1設(shè)計(jì)目的和內(nèi)容要求-5-

2.2線程描述-6-

2.3線程的創(chuàng)建和撤消-8-

2.4線程調(diào)度設(shè)計(jì)-10-

2.5基本實(shí)例程序的實(shí)現(xiàn)-23-

2.6線程的阻塞和喚醒-26-

2.7線程的同步與互斥-26-

2.8利用消息緩沖隊(duì)列通信機(jī)制實(shí)現(xiàn)線程間通信-27-

第三章簡(jiǎn)單文件系統(tǒng)的實(shí)現(xiàn)-32-

3.1設(shè)計(jì)目的和內(nèi)容要求-32-

3.2預(yù)備知識(shí)-33-

3.3實(shí)例系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)-36-

第四章:linux進(jìn)程管理-47-

4.1設(shè)計(jì)目的和內(nèi)容要求-47-

一、設(shè)計(jì)目的-47-

二、設(shè)計(jì)內(nèi)容-47-

三、思考-48-

4.2Linux基本使用:-48-

一、進(jìn)入Linux系統(tǒng)和退出Linux系統(tǒng)-48-

二、圖形化界面-49-

三、常用命令-50-

四、Linux的在線幫助man-73-

五、vi和vim編輯器-75-

六、Linux環(huán)境下C編程-79-

七、gdb調(diào)試工具-81-

4.3linux內(nèi)核模塊的編程入門(mén)-83-

一、模塊編程步驟:-84-

二、模塊編程舉例:-84-

4.4linux進(jìn)程管理系統(tǒng)調(diào)用-87-

一、linux進(jìn)程控制-87-

二、進(jìn)程通信-95-

(一)Linux管道通信機(jī)制-95-

(-)Linux消息隊(duì)列通信機(jī)制-101-

(三)linux共享內(nèi)存通信-108-

三、進(jìn)程/線程同步(信號(hào)量)-118-

(―)SystemV信號(hào)量-118-

(二)Posix信號(hào)量:-119-

操作系統(tǒng)課程設(shè)計(jì)

第一章操作系統(tǒng)課程設(shè)計(jì)的內(nèi)容與實(shí)施方法

1.1操作系統(tǒng)課程設(shè)計(jì)總體要求

1.遵守機(jī)房紀(jì)律,服從機(jī)房調(diào)度。

2.課程設(shè)計(jì)的設(shè)計(jì)和上機(jī)調(diào)試要求獨(dú)立完成,不能拷貝。

3.上機(jī)前,努力準(zhǔn)備上機(jī)內(nèi)容,并預(yù)先作一些情況分析。

4.仔細(xì)觀察上機(jī)時(shí)出現(xiàn)的各種現(xiàn)象,記錄上機(jī)的結(jié)果。

5.認(rèn)真書(shū)寫(xiě)課程設(shè)計(jì)報(bào)告。報(bào)告中應(yīng)包括:課程設(shè)計(jì)的目的及要求、程序的設(shè)計(jì)思想

及流程圖、程序調(diào)試中遇到的問(wèn)題及分析、程序代碼清單和結(jié)果分析;程序的不足之處及修

改方案等。程序要帶注釋。

1.2操作系統(tǒng)課程設(shè)計(jì)的內(nèi)容

本次課程設(shè)計(jì)共設(shè)置了以下兩個(gè)題目:

1.基于DOS的多任務(wù)系統(tǒng)的實(shí)現(xiàn)

DOS系統(tǒng)是一個(gè)典型的單用戶單任務(wù)操作系統(tǒng)?!盎贒OS的多任務(wù)系統(tǒng)的實(shí)現(xiàn)”的

基本設(shè)計(jì)思想是設(shè)計(jì)一個(gè)運(yùn)行在DOS系統(tǒng)中的應(yīng)用程序,該應(yīng)用程序能實(shí)現(xiàn)多線程機(jī)制,

即能完成所有與線程管理有關(guān)的工作,包括線程創(chuàng)建與撤銷(xiāo)、線程阻塞與喚醒、線程互斥與

同步、線程調(diào)度、線程通信等。我們利用這些功能創(chuàng)建多個(gè)線程,并調(diào)度這些線程在CPU

上并發(fā)執(zhí)行,每個(gè)線程執(zhí)行一個(gè)函數(shù)完成指定的功能。

2.簡(jiǎn)單文件系統(tǒng)的實(shí)現(xiàn)

文件系統(tǒng)是操作系統(tǒng)內(nèi)核中非常重要的組成部分之一。一個(gè)相對(duì)完整的文件系統(tǒng)應(yīng)該

具備以下幾個(gè)方面的功能:磁盤(pán)存儲(chǔ)空間管理、目錄管理、文件讀寫(xiě)管理、文件保護(hù)與共享。

由于對(duì)磁盤(pán)的存取操作必然涉及到磁盤(pán)驅(qū)動(dòng)程序設(shè)計(jì),為了降低設(shè)計(jì)難度,本實(shí)驗(yàn)的基本設(shè)

計(jì)思想是在內(nèi)存中申請(qǐng)一塊存儲(chǔ)空間作為虛擬磁盤(pán),在其上建立一個(gè)類(lèi)似于FAT的文件系

統(tǒng),所有對(duì)文件系統(tǒng)的操作都是在該虛擬磁盤(pán)空間中進(jìn)行。為了保存該文件系統(tǒng)中的內(nèi)容,

如我們創(chuàng)建的目錄、文件等,在退出文件系統(tǒng)的使用之前必須將整個(gè)虛擬磁盤(pán)上的內(nèi)容以一

個(gè)文件的形式全部保存到系統(tǒng)真正的磁盤(pán)上;以后想再次使用該文件系統(tǒng)時(shí)又必須首先從磁

盤(pán)上讀入這個(gè)文件的內(nèi)容到內(nèi)存中的虛擬磁盤(pán)上,然后才能繼續(xù)使用。

1.3操作系統(tǒng)課程設(shè)計(jì)實(shí)施方案

操作系統(tǒng)是計(jì)算機(jī)系統(tǒng)中最核心最重要的一組軟件集合,用來(lái)控制系統(tǒng)中的所有硬件及

其他軟件的運(yùn)行,各程序模塊內(nèi)部的控制流程及相互間的接口都很復(fù)雜。本課程設(shè)計(jì)雖然只

是實(shí)現(xiàn)其中的一部分功能,但對(duì)學(xué)生的綜合要求依然較高,既要求對(duì)原理知識(shí)的綜合掌握,

又要求具有一定的C語(yǔ)言編程能力,特別是“基于DOS的多任務(wù)系統(tǒng)的實(shí)現(xiàn)”這個(gè)題目,

由于要利用TurboC的interrupt類(lèi)型的函數(shù)來(lái)實(shí)現(xiàn)線程切換過(guò)程中的線程運(yùn)行現(xiàn)場(chǎng)及環(huán)境信

息的自動(dòng)保存及恢復(fù),因此程序開(kāi)發(fā)工具是采用字符型界面的TurboC。而不同學(xué)生在編程

能力上存在差異,旦大多數(shù)學(xué)生對(duì)字符型界面的開(kāi)發(fā)平臺(tái)存在畏懼心理,為了達(dá)到因材施教

的目的,保證每個(gè)學(xué)生都能根據(jù)自己的實(shí)際情況參與到課程設(shè)計(jì)過(guò)程中,我們開(kāi)發(fā)設(shè)計(jì)了一

個(gè)可視化的操作系統(tǒng)課程設(shè)計(jì)平臺(tái)軟件(該平臺(tái)軟件的使用方法見(jiàn)后面第三篇內(nèi)容),該軟

件系統(tǒng)最大的特點(diǎn)是提供了模塊式替換功能,即將每個(gè)課程設(shè)計(jì)題目的內(nèi)容分解成若干個(gè)相

對(duì)“較小”的功能模塊(模塊具體劃分情況見(jiàn)后面課程設(shè)計(jì)的詳細(xì)介紹),允許每個(gè)學(xué)生根

據(jù)自身能力情況選擇實(shí)現(xiàn)課程設(shè)計(jì)的全部或部分功能模塊,學(xué)生完成一個(gè)或多個(gè)模塊后可在

軟件系統(tǒng)中進(jìn)行模塊替換操作,替換后需要重新進(jìn)行編譯、鏈接工作,然后就可以運(yùn)行程序,

從而及時(shí)看到所編寫(xiě)模塊的功能實(shí)現(xiàn)情況。這樣能夠提高所有學(xué)生主動(dòng)學(xué)習(xí)的興趣,提高實(shí)

際動(dòng)手能力。

第二章基于DOS的多任務(wù)系統(tǒng)的實(shí)現(xiàn)

2.1設(shè)計(jì)目的和內(nèi)容要求

1.設(shè)計(jì)目的

通過(guò)對(duì)線程(和進(jìn)程)的創(chuàng)建和撤消、CPU的調(diào)度、同步機(jī)制、通信機(jī)制的實(shí)現(xiàn),達(dá)

到以下目的:

(1)加深對(duì)線程和進(jìn)程概念的理解,明確進(jìn)程和程序的區(qū)別。

(2)加深對(duì)CPU調(diào)度過(guò)程(現(xiàn)場(chǎng)保護(hù)、CPU的分派和現(xiàn)場(chǎng)恢復(fù))的理解。

(3)進(jìn)一步認(rèn)識(shí)并發(fā)執(zhí)行的概念,明確順序執(zhí)行和并發(fā)執(zhí)行的區(qū)別。

(4)加深對(duì)臨界資源、臨界區(qū)、信號(hào)量以及同步機(jī)制的理解。

(5)加深對(duì)消息緩沖通信的理解。

2.內(nèi)容要求

(1)用C語(yǔ)言完成線程的創(chuàng)建和撤消,并按先來(lái)先服務(wù)方式對(duì)多個(gè)線程進(jìn)行調(diào)度。

(2)將線程調(diào)度算法修改為時(shí)間片輪轉(zhuǎn)算法,實(shí)現(xiàn)時(shí)間片輪轉(zhuǎn)調(diào)度。(也可以結(jié)合

優(yōu)先權(quán),實(shí)現(xiàn)優(yōu)先權(quán)加時(shí)間片輪轉(zhuǎn)算法的線程調(diào)度。)

(3)改變時(shí)間片的大小,觀察結(jié)果的變化。思考:為什么時(shí)間片不能太小或太大。

(4)假設(shè)兩個(gè)線程共用同一軟件資源(如某一變量,或某一數(shù)據(jù)結(jié)構(gòu)),請(qǐng)用記錄

型信號(hào)量來(lái)實(shí)現(xiàn)對(duì)它的互斥訪問(wèn)。

(5)假設(shè)有兩個(gè)線程共享一個(gè)可存放5個(gè)整數(shù)的緩沖,其中一個(gè)線程不停地計(jì)算

1至50的平方,并將結(jié)果放入緩沖中,另一個(gè)線程不斷地從緩沖中取出結(jié)果,并將它們

打印出來(lái),請(qǐng)用記錄型信號(hào)量實(shí)現(xiàn)這一生產(chǎn)者和消費(fèi)者的同步問(wèn)題。

(6)實(shí)現(xiàn)消息緩沖通信,并與4、5中的簡(jiǎn)單通信進(jìn)行比較。

(7)思考:在線程間進(jìn)行消息緩沖通信時(shí),若對(duì)消息隊(duì)列的訪問(wèn)沒(méi)有滿足互斥要

求,情況將會(huì)怎樣?

3.學(xué)時(shí)安排(共21學(xué)時(shí))

(1)授課3學(xué)時(shí),內(nèi)容包括線程的創(chuàng)建、撤消、調(diào)度等內(nèi)容。

(2)線程的創(chuàng)建、撤消、先來(lái)先服務(wù)調(diào)度,8學(xué)時(shí)上機(jī)。

(3)時(shí)間片輪轉(zhuǎn)調(diào)度,3學(xué)時(shí)上機(jī)。

(4)信號(hào)量的實(shí)現(xiàn),3學(xué)時(shí)上機(jī)。

(5)線程間的消息緩沖隊(duì)列通信,4學(xué)時(shí)上機(jī)。

4.開(kāi)發(fā)平臺(tái)

TurboC2.0或3.0。

2.2線程描述

2.2.1線程基本概念

在一些多任務(wù)的環(huán)境下,用戶可以同時(shí)運(yùn)行多個(gè)完整的程序。例如,在UNIX環(huán)境

下,你可以用CC命令編譯一個(gè)C程序,并把它作為一個(gè)后臺(tái)進(jìn)程運(yùn)行(只需在命令行后加

上字符'&');在前臺(tái),你又可以做其他的事情,比如,編輯另一個(gè)文件。我們把這種系統(tǒng)

稱為基于進(jìn)程的多任務(wù)系統(tǒng)。另外有一種多任務(wù)系統(tǒng),在其下,一個(gè)程序的多個(gè)部分可同時(shí)

運(yùn)行,我們把這種環(huán)境下的任務(wù),即程序的每個(gè)部分叫做線程,稱這種系統(tǒng)為基于線程的多

任務(wù)系統(tǒng)。在這種環(huán)境下,處理機(jī)的調(diào)度單位為線程,它們共享整個(gè)進(jìn)程的資源,還擁有一

些自己的私有資源。我們將通過(guò)本課程設(shè)計(jì)實(shí)現(xiàn)多個(gè)線程的并發(fā)執(zhí)行。

線程,有時(shí)也叫做輕進(jìn)程(lightweightprocess),是CPU調(diào)度的基本單位,每個(gè)線程有

自己的一個(gè)指令計(jì)數(shù)器、一組寄存器和一個(gè)私有堆棧。而代碼段、數(shù)據(jù)段以及操作系統(tǒng)的其

它資源(如打開(kāi)的文件)是由一組線程共享的,這一組線程組成一個(gè)Task(傳統(tǒng)的進(jìn)程,

即heavyweightprocess相當(dāng)于只有一個(gè)線程的Task)。

在許多方面,對(duì)線程的操作類(lèi)似于進(jìn)程:線程可處于就緒、阻塞、執(zhí)行三種狀態(tài)之一;

線程可共享CPU,在單機(jī)系統(tǒng)中,任何時(shí)刻最多只能有一個(gè)線程處于執(zhí)行狀態(tài);一個(gè)Task

中的多個(gè)線程可并發(fā)執(zhí)行。但與進(jìn)程不同,一個(gè)Task中的多個(gè)線程并不互相獨(dú)立,因?yàn)椋?/p>

所有線程均可訪問(wèn)所屬Task的地址空間的任一單元,所以,一個(gè)線程讀寫(xiě)其它線程的私有

堆棧是十分容易的,即系統(tǒng)不提供線程間的保護(hù)。

注:上面講的Task是指一個(gè)完整的作業(yè),其中可包括多個(gè)線程,與本課程設(shè)計(jì)中所講

的多任務(wù)中的任務(wù)(系統(tǒng)中可并發(fā)執(zhí)行的部分,如線程或進(jìn)程)含義不同,除此之外,本課

程設(shè)計(jì)中所提到的Task或任務(wù)均代表后者。

線程的切換只需切換寄存器組的值,而不需做有關(guān)內(nèi)存管理方面的工作,實(shí)現(xiàn)起來(lái)也就

比較簡(jiǎn)單。

2.2.2線程控制塊

與進(jìn)程類(lèi)似,基于線程的多任務(wù)系統(tǒng)中的任務(wù),即線程,它不單是指靜態(tài)的、可并發(fā)執(zhí)

行的程序段本身,其實(shí)也是一個(gè)動(dòng)態(tài)的概念,是指可并發(fā)執(zhí)行的程序段及其執(zhí)行過(guò)程。因此,

我們要用一個(gè)類(lèi)似于進(jìn)程控制塊PCB的數(shù)據(jù)結(jié)構(gòu)一一線程控制塊TCB,來(lái)記錄有關(guān)描述線

程情況和控制線程運(yùn)行所需的全部信息,具體來(lái)說(shuō),在一個(gè)TCB中主要應(yīng)包括以下幾方面

的信息:

1.有關(guān)線程私有堆棧的信息

在線程調(diào)度的過(guò)程中,為了保護(hù)線程的現(xiàn)場(chǎng)信息,每個(gè)線程都必須有自己的私有堆棧。

我們把被切換線程的現(xiàn)場(chǎng)信息,包括目前各寄存器的值和下一條指令的地址都保存在它的堆

棧中,再?gòu)男戮€程的私有堆棧中恢復(fù)出一組新值來(lái)布置系統(tǒng)的寄存器,并從私有堆棧中得到

新線程的下一條指令地址。另外,每個(gè)線程中用到的局部變量也是存放在它自己的私有堆棧

中的。因此,在TCB中必須有線程的私有堆棧的信息,包括它在內(nèi)存的起始地址、堆棧

的棧頂指針的段地址和偏移等信息。

DOS中內(nèi)存的地址是20位的,而且DOS的內(nèi)存管理采用分段的方式,每個(gè)段的基址

的低4位必須為0,指令和數(shù)據(jù)的邏輯地址可用兩個(gè)16位的整數(shù)來(lái)描述,即:段地址seg

和段內(nèi)偏移off,其中段地址seg中有段基址的高16位,故邏輯地址seg:off對(duì)應(yīng)的物理地址

為segXZ,+off。C語(yǔ)言經(jīng)常用指針來(lái)描述一個(gè)地址,TurboC提供了三個(gè)宏函數(shù)用來(lái)實(shí)現(xiàn)指

針?lè)绞降蕉蔚刂贰⑵频刂贩绞降南嗷マD(zhuǎn)換:若P為一個(gè)指針,則可通過(guò)FP_SEG(p)得到該

地址的段地址,F(xiàn)P_OFF(p)得到該地址的段內(nèi)偏移;若seg為一個(gè)地址的段地址,off為其段

內(nèi)偏移,則可通過(guò)MK_FP(seg,off)得到對(duì)應(yīng)的指針。

2.有關(guān)線程的狀態(tài)的信息

在基于線程的多任務(wù)系統(tǒng)中,一個(gè)線程的狀態(tài)在它的生命周期中是在不斷地變化的,在

此,我們把線程的主要狀態(tài)劃分為:就緒、執(zhí)行、阻塞和終止態(tài)。如果,一個(gè)線程擁有CPU,

我們就說(shuō)它處于執(zhí)行態(tài);如果它現(xiàn)在雖不在執(zhí)行,但一旦獲得CPU就可執(zhí)行,我們就說(shuō)它

處于就緒態(tài);如果它在等待CPU以外的其他資源,則說(shuō)它處于阻塞狀態(tài);如果線程所對(duì)應(yīng)

的程序段已運(yùn)行完畢,則它處于終止?fàn)顟B(tài)。因此,在TCB中要設(shè)置一狀態(tài)字段,用來(lái)記錄

各線程的現(xiàn)行狀態(tài)。

3.線程的標(biāo)識(shí)符

線程標(biāo)識(shí)符用于惟一地標(biāo)識(shí)一個(gè)線程,與進(jìn)程一樣,通常一個(gè)線程有兩個(gè)標(biāo)識(shí)符:

(1)外部標(biāo)識(shí)符:它由創(chuàng)建者提供,通常是一個(gè)由字母、數(shù)字組成的字符串,記錄在

線程的TCB中。

(2)內(nèi)部標(biāo)識(shí)符,它通常是一個(gè)整數(shù),由多任務(wù)系統(tǒng)在創(chuàng)建線程時(shí)設(shè)置。在本課程設(shè)

計(jì)中,我們?cè)诙嗳蝿?wù)系統(tǒng)的初始化過(guò)程中,設(shè)置了一個(gè)struct類(lèi)型的TCB數(shù)組來(lái)統(tǒng)一為各

新建線程提供空白TCB,為了簡(jiǎn)單起見(jiàn),我們可以隱含地用各線程所分配到的TCB在整個(gè)

TCB數(shù)組中的下標(biāo)來(lái)表示該線程的內(nèi)部標(biāo)識(shí)符,所以不需要再專門(mén)記錄在TCB中了。

4.其它信息

TCB中記錄的信息量可隨系統(tǒng)的復(fù)雜情況而變化,如當(dāng)采用優(yōu)先權(quán)算法進(jìn)行調(diào)度時(shí),在

TCB中還必須設(shè)置優(yōu)先權(quán)字段;當(dāng)TCB要按某種方式排隊(duì)時(shí),在其中必須設(shè)置一鏈接指針

字段;當(dāng)必須喚醒因某種原因而阻塞的相關(guān)線程時(shí),則必須設(shè)置阻塞原因字段;在使用消息

緩沖隊(duì)列機(jī)制實(shí)現(xiàn)線程通信時(shí),則必須設(shè)置通信機(jī)制需要的字段,如接收線程的消息隊(duì)列隊(duì)

首指針、消息隊(duì)列的互斥信號(hào)量和資源信號(hào)量等。

用C語(yǔ)言來(lái)描述,一個(gè)最簡(jiǎn)單的TCB的數(shù)據(jù)結(jié)構(gòu)可以表示如下:

/*狀態(tài)碼常量定義*/

/*null0notassigned*/

#defineFINISHED0/*表示線程處于終止態(tài)或TCB是空白狀態(tài)*/

#defineRUNNING1/*表示線程處于運(yùn)行態(tài)*/

#defineREADY2/*表示線程處于就緒態(tài)*/

#defineBLOCKED3/*表示線程處于阻塞態(tài)*/

structTCB{

unsignedchar*stack;/*線程堆棧的起始地址*/

unsignedss;/*堆棧段址*/

unsignedsp;/*堆棧指針*/

charstate;/*線程狀態(tài),取值可以是FINISHED、RUNNING.READY、BLOCKED*/

charname[10];/*線程的外部標(biāo)識(shí)符*/

}tcbfNTCB];/*NTCB是系統(tǒng)允許的最多任務(wù)數(shù)*/

2.3線程的創(chuàng)建和撤消

2.3.1線程的創(chuàng)建

在創(chuàng)建一個(gè)新線程時(shí),線程的創(chuàng)建者必需提供一些信息,如線程的外部標(biāo)識(shí)符、線程所

需的私有堆??臻g的大小、與線程所對(duì)應(yīng)的程序段的入口地址的有關(guān)信息(這里假設(shè)一個(gè)線

程執(zhí)行程序里的一個(gè)函數(shù),所以創(chuàng)建者只需提供線程要執(zhí)行的函數(shù)的函數(shù)名即可)。

1.線程創(chuàng)建函數(shù)格式說(shuō)明

(1)函數(shù)申明原型:typedefint(far*codeptr)(void);/*定義了一個(gè)函數(shù)指針類(lèi)型*/

Intcreate(char*name,codeptrcode,intstck);

(2)函數(shù)功能描述:在main。函數(shù)中調(diào)用,創(chuàng)建一個(gè)新線程,讓其執(zhí)行code開(kāi)始的代

碼。

(3)輸入:

name:新創(chuàng)建線程的外部標(biāo)識(shí)符;

code:新創(chuàng)建線程要執(zhí)行的代碼的入口地址,此處用函數(shù)名作為傳入地址;

stck:新創(chuàng)建線程的私有堆棧的長(zhǎng)度。

(4)輸出:新創(chuàng)建線程的內(nèi)部標(biāo)識(shí)符,若創(chuàng)建失敗,返回-1

2.函數(shù)實(shí)現(xiàn)的算法描述

在創(chuàng)建一個(gè)線程時(shí)主要應(yīng)完成以下工作:

(1)為新線程分配一個(gè)空閑的線程控制塊TCB,該TCB的數(shù)組下標(biāo)即為新線程

的內(nèi)部標(biāo)識(shí)符。如果沒(méi)有空閑的TCB,則返回-1,創(chuàng)建失敗。

(2)為新線程的私有堆棧分配內(nèi)存空間(因?yàn)橥贿M(jìn)程的多個(gè)線程共享該進(jìn)程的

程序段和數(shù)據(jù)段空間,所以創(chuàng)建線程時(shí)不必象創(chuàng)建進(jìn)程那樣再為程序段和數(shù)據(jù)段分配內(nèi)存空

間)。

(3)初始化新線程的私有堆棧,即按CPU調(diào)度時(shí)現(xiàn)場(chǎng)信息的保存格式布置堆棧,

這一點(diǎn)是非常重要的,因?yàn)楫?dāng)CPU首次調(diào)度該線程運(yùn)行時(shí),CPU中的SS寄存器和SP寄存

器將指向該線程的私有堆棧,并從該堆棧中獲得線程運(yùn)行的正確的指令地址和其它現(xiàn)場(chǎng)信

息。新線程的首次執(zhí)行是從對(duì)應(yīng)函數(shù)的入口開(kāi)始的;而且,執(zhí)行時(shí)CPU的寄存器ES、DS

應(yīng)置上恰當(dāng)?shù)闹?;Flags寄存器的允許中斷位也應(yīng)置上1,這樣,線程執(zhí)行過(guò)程中才允許硬

中斷(如時(shí)鐘中斷)發(fā)生并及時(shí)響應(yīng)中斷;其它寄存器(AX、BX、CX、DX、SLDLBP)

的值只在線程執(zhí)行過(guò)程中才有意義,它們的初值可為任意值。初始化工作完成后堆棧中各信

息項(xiàng)的值及其相應(yīng)位置如圖2-lb所示。

為了方便堆棧的初始化工作,我們可以按照堆棧中的內(nèi)容設(shè)計(jì)一個(gè)以下的數(shù)據(jù)結(jié)構(gòu):

structint_regs{

unsignedbp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flags,off,seg;

);

然后用一個(gè)指向該數(shù)據(jù)結(jié)構(gòu)的指針給堆棧賦值。

(4)初始化線程控制塊,即填入線程的外部標(biāo)識(shí)符,設(shè)置好線程私有堆棧的始址、

段址和棧頂指針,將線程的狀態(tài)置成就緒態(tài)READY,如圖2-la所示。

另外,如果線程調(diào)度算法是按優(yōu)先權(quán)方式進(jìn)行CPU調(diào)度,則需在TCB中置上新線程的

優(yōu)先權(quán)信息(初始優(yōu)先數(shù)可由用戶提供);若TCB的組織方式是按某種方式拉鏈,系統(tǒng)設(shè)置

了線程就緒隊(duì)列,則還需將新線程的TCB插入就緒隊(duì)列;如果要實(shí)現(xiàn)通信,還需要將線程

的消息隊(duì)列隊(duì)首指針設(shè)置為Nun、消息隊(duì)列的互斥信號(hào)量和資源信號(hào)量分別設(shè)置為{1,Null}

和{0,Null}

(5)最后,返回新線程的內(nèi)部標(biāo)識(shí)符。

在TurboC的small編譯模式下,調(diào)用create("f1",(codeptr)f1,1024)創(chuàng)建一個(gè)對(duì)應(yīng)于函

數(shù)fl()的線程后新線程的內(nèi)存映象如圖2-1所示。

線程私有

堆棧空間

—59ba:63e

TCB集

S59ba:a22

?新sp

BP

TCB(O)線函數(shù)fl()

程DI\57f7:879

初SI

始DS:59ba

現(xiàn)ES:59ba

場(chǎng)DX

stack:63e信CX

TCB(i)ss:59ba息BX

sp:a22AX

state:READY函數(shù)

IP:879over()

name:“fl”

CS:57f757f7:466

Flags:200

Fl()返址

off:466

seg:57f7

TCB(NTCB-l)59ba:a3e

圖a圖b

圖2-1對(duì)應(yīng)函數(shù)fl()的新線程的內(nèi)存映像

2.3.2線程的撤消

引起線程撤銷(xiāo)的原因主要有兩個(gè):一是系統(tǒng)或用戶要求撤銷(xiāo)某個(gè)線程;二是當(dāng)前線程所

對(duì)應(yīng)的函數(shù)已經(jīng)運(yùn)行完成。對(duì)于第一種情況比較簡(jiǎn)單,只需調(diào)用線程撤銷(xiāo)原語(yǔ)將指定線程撤

銷(xiāo)即可;對(duì)于第二鐘情況,首先必須自動(dòng)調(diào)用線程撤銷(xiāo)原語(yǔ)撤銷(xiāo)當(dāng)前已經(jīng)運(yùn)行完成的線程,

然后還需要自動(dòng)地重新進(jìn)行CPU調(diào)度。

1.線程撤銷(xiāo)函數(shù)設(shè)計(jì):

(1)函數(shù)申明原型:voiddestroy(intid);

(2)功能:撤銷(xiāo)內(nèi)部標(biāo)識(shí)符為id的指定線程。

(3)輸入:

id:將要被撤銷(xiāo)的線程的內(nèi)部標(biāo)識(shí)符。

(4)輸出:無(wú)

(5)函數(shù)實(shí)現(xiàn)的算法描述:

撤銷(xiāo)線程所要完成的工作比較簡(jiǎn)單,主要是將線程所占據(jù)的資源歸還給系統(tǒng)。在操作系

統(tǒng)原理中已經(jīng)介紹了線程本身基本不占據(jù)資源,它與同進(jìn)程的其他線程共享該進(jìn)程的代碼段

和數(shù)據(jù)段空間;但是線程作為一個(gè)可以獨(dú)立調(diào)度和運(yùn)行的基本單元也擁有一些必不可少的資

源,如線程控制塊TCB和私有堆棧。所以撤銷(xiāo)線程所要做的事情主要就是兩個(gè):

(1)將線程的私有堆棧所占的內(nèi)存空間歸還給系統(tǒng);

(2)將線程控制塊TCB的各成員變量進(jìn)行初始化操作。

2.撤銷(xiāo)線程并重新進(jìn)行調(diào)度

前面提到如果是因?yàn)楫?dāng)前線程運(yùn)行完成而引起線程撤消,則系統(tǒng)應(yīng)能自動(dòng)撤消該線程,

并重新進(jìn)行CPU調(diào)度。我們可以設(shè)置一個(gè)稱為over()的函數(shù)來(lái)完成這個(gè)工作,該函數(shù)需

要順序做兩件事情:首先調(diào)用destroy()撤銷(xiāo)當(dāng)前線程,然后重新進(jìn)行CPU調(diào)度。所以現(xiàn)

在關(guān)鍵的問(wèn)題是在當(dāng)前線程運(yùn)行完成后CPU應(yīng)能自動(dòng)轉(zhuǎn)去執(zhí)行overO,這可通過(guò)在創(chuàng)建線

程時(shí)進(jìn)行一些相關(guān)的處理來(lái)實(shí)現(xiàn):在進(jìn)行堆棧初始化時(shí)可預(yù)先將。ver()的入口地址壓入線

程的私有堆棧中,如前面圖2-3b所示;這樣,當(dāng)線程所對(duì)應(yīng)的函數(shù)正常結(jié)束時(shí),over。函數(shù)

的入口地址將作為函數(shù)的返回地址被彈出至CPU的CS、1P寄存器,從而使CPU的控制權(quán)

自動(dòng)轉(zhuǎn)向over。去執(zhí)行。

2.4線程調(diào)度設(shè)計(jì)

2.4.1CPU調(diào)度中的關(guān)鍵問(wèn)題

CPU調(diào)度所要做的事情是保護(hù)舊線程的現(xiàn)場(chǎng)、找到新線程、恢復(fù)新線程的現(xiàn)場(chǎng)、并把

處理機(jī)交給新線程讓它執(zhí)行。其中,找一新線程是比較容易實(shí)現(xiàn)的,只需按某種線程調(diào)度算

法從所有處于就緒狀態(tài)的線程中選擇一個(gè)即可;剩余的問(wèn)題一一舊線程的現(xiàn)場(chǎng)保護(hù)和新線程

的現(xiàn)場(chǎng)恢復(fù)、CPU控制權(quán)的轉(zhuǎn)移才是CPU調(diào)度的關(guān)鍵,它們是通過(guò)堆棧的切換來(lái)實(shí)現(xiàn)的。

在介紹堆棧切換的內(nèi)容之前,我們先來(lái)看看函數(shù)調(diào)用和進(jìn)行中斷處理時(shí)控制轉(zhuǎn)移的情況。

1.函數(shù)調(diào)用時(shí)的控制轉(zhuǎn)移情況

在執(zhí)行函數(shù)調(diào)用指令時(shí),系統(tǒng)會(huì)自動(dòng)地先將主調(diào)函數(shù)的下一條指令的地址(在CS:IP中)壓入堆棧,

然后把被調(diào)函數(shù)的入口地址裝入CS和IP寄存器(段內(nèi)函數(shù)調(diào)用只需壓入和裝配IP),控制就從主調(diào)函

數(shù)轉(zhuǎn)向被調(diào)函數(shù);當(dāng)執(zhí)行函數(shù)返回指令時(shí),系統(tǒng)將當(dāng)前堆棧的棧頂?shù)膬蓚€(gè)字(主調(diào)函數(shù)下一條指令的地

址)彈出并送到IP和CS中(段內(nèi)函數(shù)返回只需彈出一個(gè)字送到IP中),控制就從被調(diào)函數(shù)返回到主調(diào)

函數(shù)。

例如,我們編寫(xiě)了一個(gè)main()函數(shù)和一個(gè)fl()函數(shù),在main()中調(diào)用fl()。程序的設(shè)計(jì)

及調(diào)用返回關(guān)系如圖2-2所示:

voidfl(void);

inti;

main()

(函數(shù)調(diào)用進(jìn)fl()

i=0;入被調(diào)函數(shù)(

fl();-—Ai=2;

?1—1;■return;

返址1函數(shù)返回

})

圖2-2函數(shù)調(diào)用及返回圖

在執(zhí)行fl()函數(shù)的調(diào)用指令前的當(dāng)前堆棧的情況如圖2-3a所示。在執(zhí)行函數(shù)調(diào)用指令

時(shí),系統(tǒng)首先將main()中函數(shù)調(diào)用語(yǔ)句的下一條指令即“i=l;”的地址(在CS:IP中,這

里用“返址1”表示)壓入堆棧,此時(shí)堆棧內(nèi)容如圖2-3b所示。然后將fl()函數(shù)的入口地址

裝入CS和IP寄存器,控制就從main。轉(zhuǎn)向fl()。當(dāng)執(zhí)行fl()的最后一條指令"return”(函

數(shù)返回指令)時(shí),系統(tǒng)將前面保存在堆棧中的返址1的偏移和返址1的段址彈出并送到IP

和CS中,則控制就從fl()返回到main。了。

sp

返址1的偏移調(diào)用fl()

返址1的段址后的棧頂

從口()返回

后的棧頂

圖a調(diào)用fl()前的棧頂圖b調(diào)用f1()后的棧頂圖c從fl()返回后的棧頂

圖2-3函數(shù)調(diào)用前后堆棧內(nèi)容的變化

2.中斷處理時(shí)的控制轉(zhuǎn)移情況

除了函數(shù)調(diào)用以外,中斷也能實(shí)現(xiàn)控制的轉(zhuǎn)移。當(dāng)中斷發(fā)生時(shí),系統(tǒng)首先將標(biāo)志寄存器

Flags的值壓入堆棧,然后將裝有被中斷程序下一條指令地址的CS和IP寄存器的內(nèi)容也分

別壓入堆棧,再?gòu)闹袛嘞蛄恐蝎@取中斷服務(wù)程序的入口地址并將它們裝入CS和IP寄存器,

這樣,控制就從被中斷的程序轉(zhuǎn)向中斷服務(wù)程序.中斷返回時(shí),系統(tǒng)自動(dòng)從棧頂彈出返址1

的偏移、返址1的段址和Flags并送到IP、CS和Flags寄存器中,CPU就開(kāi)始繼續(xù)從斷點(diǎn)

處執(zhí)行被中斷程序。中斷處理前后堆棧內(nèi)容的變化情況如圖2-4所示:

sp

返址1的偏移進(jìn)入中斷處

返址1的段址理時(shí)的棧頂

中斷處理返

回后的棧頂

圖a中斷處理前的棧頂圖b進(jìn)入中斷處理時(shí)的棧頂圖c中斷處理返回后的棧頂

圖2-4中斷處理前后堆棧內(nèi)容的變化

3.Interrupt類(lèi)型函數(shù)的特殊作用

在TurboC中提供了一個(gè)特殊的函數(shù)類(lèi)型說(shuō)明符interrupt,我們可利用它將一個(gè)函數(shù)申

明為中斷處理函數(shù)。例如我們寫(xiě)了一個(gè)文件名為“aaa.c”的C程序,其內(nèi)容如下:

voidinterruptfun(void);

inti;

main()

(

i=0;

fun();

i=l;

)

voidinterruptfun(void)

(

i=2;

}

用編譯命令"tcc?Saaa”得到以上C程序的匯編碼:

ifndef??version

?debugmacro

endm

endif

?debugS"

_TEXTsegmentbytepublic'CODE,

DGROUPgroup_DATA,_BSS

assumecs:_TEXT,ds:DGROUP,ss:DGROUP

_TEXTends

_DATAsegmentwordpublic'DATA'

d@labelbyte

d@wlabelword

_DATAends

_BSSsegmentwordpublic'BSS'

b@labelbyte

b@wlabelword

?debugCE93B4F151F056161612E63

_BSSends

_TEXTsegmentbytepublic'CODE'

;?debugL3

_mainprocnear

;?debugL4

movwordptrDGROUP:_i,0

;?debugL5

pushf

callfarptr_fun

;?debugL6

movwordptrDGROUP:_i,l

@1:

;?debugL7

ret

_mainendp

;?debugL8

_funprocfar

pushax

pushbx

pushex

pushdx

pushes

pushds

pushsi

pushdi

pushbp

movbp,DGROUP

movds,bp

;?debugL10

movwordptrDGROUP:_i,2

@2:

;?debugL11

popbp

popdi

popsi

popds

popes

popdx

popex

popbx

popax

iret

_funendp

.TEXTends

_BSSsegmentwordpublic'BSS'

_ilabelword

db2dup(?)

_BSSends

?debugCE9

_DATAsegmentwordpublic'DATA,

s@labelbyte

_DATAends

_TEXTsegmentbytepublicCODE'

_TEXTends

public_main

public_fun

public_i

end

從編譯后的代碼中可以看出,對(duì)于fun()函數(shù),由于定義的類(lèi)型是interrupt類(lèi)型的中斷

處理函數(shù),所以在使用tcc命令進(jìn)行編譯時(shí),編譯器將自動(dòng)在fun()的開(kāi)始加入一組push操

作(代碼中第二組黑體字部分),以保存被中斷程序的CPU現(xiàn)場(chǎng)環(huán)境信息;相對(duì)應(yīng)地在fun()

的代碼最后自動(dòng)加入一組pop操作(代碼中第三組黑體字部分),以便中斷返回時(shí)恢復(fù)被中

斷程序的現(xiàn)場(chǎng)環(huán)境信息。

從編譯后的代碼段中還可以看出,main。對(duì)fun。的調(diào)用是通過(guò):

pushf

callfarptr_fun/*代碼中的第一組黑體字部分*/

實(shí)現(xiàn)的,即先壓入Flags寄存器的內(nèi)容,再用call指令壓入返回地址,并轉(zhuǎn)去執(zhí)行fun()函數(shù)。

而在進(jìn)入fun()時(shí),系統(tǒng)首先將執(zhí)行一組push操作,將AX、BX、CX、DX、ES、DS、SL

DLBP的值保存到堆棧中,再用fun()的數(shù)據(jù)段裝配DS寄存器,然后才執(zhí)行fun()中的具

體語(yǔ)句“i=2;”。而在返回前,先要執(zhí)行一組pop操作,從堆棧中恢復(fù)BP、DLSLDS、ES、

DX、CX、BX、AX的值,然后再用iret指令(而不是ret指令)返回,iret指令將從堆棧

中彈出返址的偏移、返址的段址、flags到CPU的IP、CS和Flags寄存器中,從而使CPU

繼續(xù)從斷點(diǎn)處執(zhí)行被中斷程序main()ofun()調(diào)用前后的堆棧內(nèi)容如圖2-5所示,圖中的“返

址1”是指main。函數(shù)中fun()函數(shù)調(diào)用指令的下一條指令“i=l”的地址。

BPsp

DIfun()執(zhí)行

SIpush操作后

DS

ES的棧頂

DX

CX

BX

AX

sp

返址1的偏移調(diào)用fun()返址1的偏移

返址1的段址時(shí)的棧頂返址1的段址

FlagsFlags

sp

調(diào)用fun()

前的棧頂

圖a調(diào)用fun()前的棧頂圖b調(diào)用fun()時(shí)的棧頂圖cfun()執(zhí)行push操作后

的棧頂

sp

返址1的偏移fun()執(zhí)行

pop操作后

返址1的段址

的棧頂

Flags

sp

從fun()返回

后的棧頂

圖dfun()執(zhí)行pop操作后圖e從fun()返回后的棧頂

的棧頂

圖2-5fun()調(diào)用前后的堆棧內(nèi)容的變化

4.利用堆棧切換實(shí)現(xiàn)CPU切換

從上面的描述可知,我們可以用函數(shù)或中斷服務(wù)子程序來(lái)處理CPU的切換,但關(guān)鍵仍

在于堆棧的切換。例如,系統(tǒng)中有兩個(gè)線程:線程1和線程2,它們的私有堆棧分別為stack1

和stack2;線程1目前擁有CPU,即線程1正在執(zhí)行,則系統(tǒng)的現(xiàn)行堆棧為線程1的私有堆

棧stack1;在線程1中調(diào)用一函數(shù)F(),函數(shù)的返回地址即線程1的下一條指令的地址將壓

入到現(xiàn)行堆棧stackl中;若在F()中,將系統(tǒng)的現(xiàn)行堆棧從stackl切換到stack2:保存現(xiàn)行

堆棧的段址SS和棧頂指針SP到變量ssl、spl中,并將線程2的堆棧stack2的段址和棧頂

指針裝到CPU的SS與SP寄存器中;如果stack2的棧頂有線程2的下一條指令的地址,則

從F()中返回時(shí),將用現(xiàn)行堆棧stack2的棧頂?shù)淖盅b配IP和CS,CPU就開(kāi)始執(zhí)行新線程,

即線程2。若再用保存在變量ssl、spl中的內(nèi)容來(lái)裝配SS和SP寄存器,即將現(xiàn)行堆棧切

換回線程1的私有堆棧,則CPU將被分配給線程1,它將從原來(lái)的斷點(diǎn)繼續(xù)往下執(zhí)行???/p>

慮到CPU切換時(shí)要進(jìn)行現(xiàn)場(chǎng)保護(hù),用中斷服務(wù)子程序來(lái)實(shí)現(xiàn)CPU的切換就顯得更方便。

下面我們用interrupt類(lèi)型的函數(shù)swtch()來(lái)實(shí)現(xiàn)CPU在線程1和線程2間的切換,另外,

必須注意的是,在堆棧切換過(guò)程中一定要做到操作的原子性,這一點(diǎn)我們可以通過(guò)關(guān)中斷、

開(kāi)中斷來(lái)達(dá)到。Swtch()的設(shè)計(jì)如下:

voidinterruptswtch(void)

(

disable();/*關(guān)中斷*/

/*保存現(xiàn)行堆棧的段址和棧頂指針供下次切換時(shí)用*/

ssl=_SS;/*ssl保存線程1的堆棧段址*/

spl=_SP;/*spl保存線程1的堆棧棧頂指針*/

/*切換堆棧*/

_SS=ss2;/*ss2是線程2的堆棧段址*/

_SP=sp2;/*ss2是線程2的堆棧的棧頂指針*/

enable();/*開(kāi)中斷*/

)

上面代碼中用到的一SS,_SP是TurboC提供的偽變量。所謂的偽變量是一個(gè)和給定寄

存器相一致的簡(jiǎn)單的標(biāo)識(shí)符,通過(guò)它們,我們可以在C語(yǔ)言程序中直接訪問(wèn)相應(yīng)的寄存器。

表2-1中給出了TurboC可用的偽變量的完整列表、它們的類(lèi)型、相應(yīng)的寄存器以及那些寄

存器通常的用處。

表2-1TurboC偽變量表

偽變量類(lèi)型寄存器通常用處

_AX無(wú)符號(hào)整型AX通用/累加器

_AL無(wú)符號(hào)字符型ALAX的低字節(jié)

_AH無(wú)符號(hào)字符型AHAX的高字節(jié)

_BX無(wú)符號(hào)整型BX通用/變址器

_BL無(wú)符號(hào)字符型BLBX的低字節(jié)

_BH無(wú)符號(hào)字符型BHBX的高字節(jié)

_CX無(wú)符號(hào)整型CX通用/計(jì)數(shù)和循環(huán)

_CL無(wú)符號(hào)字符型CLCX的低字節(jié)

_CH無(wú)符號(hào)字符型CHCX的高字節(jié)

_DX無(wú)符號(hào)整型DX通用/存放數(shù)據(jù)

_DH無(wú)符號(hào)字符型DHDX的高字節(jié)

_CS無(wú)符號(hào)整型CS代碼段地址

_DS無(wú)符號(hào)整型DS數(shù)據(jù)段地址

_SS無(wú)符號(hào)整型SS堆棧段地址

_ES無(wú)符號(hào)整型ES附加段地址

_SP無(wú)符號(hào)整型SP堆棧棧頂指針(對(duì)SS

的偏移)

_BP無(wú)符號(hào)整型BP基址指針

_DI無(wú)符號(hào)整型DI用于寄存器變量

_S1無(wú)符號(hào)整型SI用于寄存器變量

由于swtch。是interrupt類(lèi)型的函數(shù),因此編譯后的偽代碼如圖2-6b所示:

swtch()

圖a線程1的程序段圖bswtch()內(nèi)容圖c線程2的程序段

圖2-6堆棧切換過(guò)程中CPU控制的轉(zhuǎn)移情況

假設(shè)線程1對(duì)應(yīng)的程序段如圖2-6a所示,線程2對(duì)應(yīng)的程序段如圖2-6c所示。又假設(shè)

現(xiàn)在是線程1正在CPU上運(yùn)行,則當(dāng)前堆棧是線程1的堆棧stackl,其內(nèi)容如圖2-7a所示。

線程2目前處于就緒狀態(tài),其堆棧stack2的內(nèi)容如圖2?8a所示。

ssl:spl

BPswtch。執(zhí)行

D1

SIpush操作后

DS的棧頂

ES

DX

CX

BX

AX

地址1的偏移

地址1的段址

Flags

圖a線程1調(diào)用swtch()圖b線程1調(diào)用swtch()圖cswtch()執(zhí)行push

前的stackl的棧頂時(shí)的stackl的棧頂操作后stackl的內(nèi)容

圖2-7CPU切換過(guò)程中線程1堆棧stackl的變化情況

ss2:sp2

BP

DI

SI

DS原來(lái)保

ES存在棧

枝中的線

BX程2的現(xiàn)

AX場(chǎng)信息

地址2的偏移

地址2的段址

Flags

<

swtch()返回

后的棧頂

圖a線程2處于就緒狀圖bswtch()執(zhí)行pop圖cswtch()返回

態(tài)時(shí)的stack2的內(nèi)容操作后stack2的內(nèi)容后stack2的內(nèi)容

圖2-8CPU切換過(guò)程中線程2堆棧stack2的變化情況

下面我們來(lái)分析CPU從線程1切換到線程2的過(guò)程中控制的轉(zhuǎn)移情況以及堆棧的變化

情況。

(1)線程1執(zhí)行swtch()函數(shù)調(diào)用指令,系統(tǒng)首先將Flags、地址1的段址、地址1的

偏移壓棧,此時(shí)stackl的內(nèi)容如圖2-7b所示。

(2)然后CPU轉(zhuǎn)去執(zhí)行swtch(),首先執(zhí)行一組push操作,由于此時(shí)的當(dāng)前堆棧仍然

是線程1的stackl,因此push操作執(zhí)行完畢后stackl的內(nèi)容如圖2-7c所示。

(3)接下來(lái)swtch()進(jìn)行堆棧切換:首先保存線程1的堆棧stackl的段址和棧頂指針到

變量ssl和spl中;然后將線程2的堆棧stack2的段址和棧頂指針裝配到CPU的SS好SP

寄存器中,則從現(xiàn)在開(kāi)始,系統(tǒng)的當(dāng)前堆棧已經(jīng)變成了stack2。

(4)接著swtch()執(zhí)行一組pop操作,將stack2中從BP開(kāi)始到AX結(jié)束的所有內(nèi)容彈

出并裝入CPU的相應(yīng)寄存器中,此時(shí)stack2的內(nèi)容如圖2-8b所示。

(4)最后swtch()執(zhí)行中斷返回指令"iret”,從stack2中彈出線程2的偏移、線程2的

段址和Flags并送到CPU的IP.CS和FLAGS寄存器中,此時(shí)stack2的內(nèi)容如圖2-8c所示。

(5)CPU繼續(xù)執(zhí)行CS:IP寄存器所指向的指令,即線程2的地址2這個(gè)位置的指令。

于是CPU的控制權(quán)從線程1切換到線程2。

2.4.2DOS的不可重入性

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論