2023年计算机操作系统实验报告_第1页
2023年计算机操作系统实验报告_第2页
2023年计算机操作系统实验报告_第3页
2023年计算机操作系统实验报告_第4页
2023年计算机操作系统实验报告_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

操作系统实验报告

学院:计算机与通信工程学院

专业:计算机科学与技术

班级:______________________

学号:______________________

姓名:______________________

指导教师:______________________

成绩:______________________

2023年1月1日

实验一线程的状态和转换(5分)

1实验目的和规定

目的:熟悉线程的状态及其转换,理解线程状态转换与线程调度的关系。

规定:

(1)跟踪调试EOS线程在各种状态间的转换过程,分析EOS中线程状态及其转换的相关

源代码;

(2)修改EOS的源代码,为线程增长挂起状态。

2完毕的实验内容

2.1EOS线程状态转换过程的跟踪与源代码分析

(分析EOS中线程状态及其转换的核心源代码,说明EOS定义的线程状态以及状态转换

的实现方法:给出在本部分实验过程中完毕的重要工作,涉及调试、跟踪与思考等)

1.EOS准备了一个控制台命令"loop",这个命令的命令函数是ke/sysproc.

c文献中的ConsoleCmdLoop函数(第797行,在此函数中使用LoopThread

Function函数(第755行)创建了一个优先级为8的线程(后面简称为“loop线

程”),该线程会在控制台中不断的(死循环)输出该线程的ID和执行计数,执行计数会

不断的增长以表达该线程在不断的运营。loop命令执行的效果可以参见下

图:

2.线程由阻塞状态进入就绪状态

(1)在虚拟机窗口中按下一次空格键。

(2)此时EOS会在PspUnwaitThread函数中的断点处中断。在“调试”菜单

中选择“快速监视”,在快速监视对话框的表达式编辑框中输入表达式“*Thread”,

然后点击“重新计算”按钮,即可查看线程控制块(TCB)中的信息。其中State域

的值为3(Waiting),双向链表项StateListEntry的Next和Prev指针的值

都不为0,说明这个线程还处在阻塞状态,并在某个同步对象的等待队列中;StartA

ddr域的值为lopConsoleDispatchThread,说明这个线程就是控制台派遣线程。

(3)关闭快速监视对话框,激活“调用堆栈”窗口。根据当前的调用堆栈,可以看到

是由键盘中断服务程序(Kdblsr)进入的。当按下空格键后,就会发生键盘中断,从而

触发键盘中断服务程序。在该服务程序的最后中会唤醒控制台派遣线程,将键盘事件派

遣到活动的控制台。

(4)在“调用堆栈”窗口中双击PspWakeThread函数相应的堆栈项。可以看

到在此函数中连续调用了PspUnwaitThread函数和PspReadyThread函数,从而

使处在阻塞状态的控制台派遣线程进入就绪状态。

(5)在“调用堆栈”窗口中双击PspUnwaitThread函数相应的堆栈项,先来看

看此函数是如何改变线程状态的。按F10单步调试直到此函数的最后,然后再从快速监

视对话框中观测“*Thread”表达式的值。此时State域的值为0(Zer。),双向链

表项StateListEntry的Next和Prev指针的值都为0,说明这个线程已经处在游离状态,

并已不在任何线程状态的队列中。仔细阅读PspUnwaitThread函数中的源代码,理解

这些源代码是如何改变线程状态的。

(6)按尸5继续执行,在PspReadyThread函数中的断点处中断。按F10单步调试

直到此函数的最后,然后再从快速监视对话框中观测“*Thread”表达式的值。此时S

tate域的值为1(Ready),双向链表项StateListEntry的Next和Prev指针的值

都不为0,说明这个线程已经处在就绪状态,并已经被放入优先级为24的就绪队列中

3.线程由运营状态进入就绪状态

(1)按F5继续执行,在PspSe1ectNextThread函数中的断点处中断。在

快速监视对话框中查看“*PspCurrentThread”表达式的值,观测当前占用解

决器的线程的情况。其中State域的值为2(Running),双向链表项StateList

Entry的Next和Prev指针的值都为0,说明这个线程仍然处在运营状态,由于只能

有一个处在运营状态的线程,所以这个线程不在任何线程状态的队列中;StartAddr

域的值为LoopThreadFunction,说明这个线程就是1oop线程。注意,在本次断

点被命中之前,1oop线程就已经被中断执行了,并且其上下文已经保存在线程控制块

中。

(2)按F10单步调试,直到对当前线程的操作完毕(也就是花括号中的操作完

毕)。再从快速监视对话框中查看"*PspCurrentThread”表达式的值。其中

State域的值为1(Ready),双向链表项StateListEntry的Next和Prev指针的

值都不为0,说明1oop线程已经进入了就绪状态,并已经被放入优先级为8的就绪队列

中。仔细阅读PspSelectNextThread函数这个花括号中的源代码,理解这些源代

码是如何改变线程状态的,并与PspReadyThread函数中的源代码进行比较,说明这两

段源代码的异同,体会为什么在这里不能直接调用PspReadyThread函数。

4.线程由就绪状态进入运营状态

(1)按F5继续执行,在PspUnreadyThread函数中的断点处中断。在快速监

视对话框中查看“*Thread”表达式的值。其中State域的值为1(Ready),双向链表

项StateListEntry的Next和Prev指针的值都不为0,说明这个线程处在就绪状

态,并在优先级为24的就绪队列中;StartAddr域的值为lopConsoleD

ispatchThread,说明这个线程就是控制台派遣线程。

(2)关闭快速监视对话框后,在“调用堆栈”窗口中激活PspSelectNextThread

函数相应的堆栈项,可以看到在PspSelectNextThread函数中已经将PspCurre

ntThread全局指针指向了控制台派遣线程,并在调用PspUnreadyThread函数

后,将当前线程的状态改成了Running。

(3)在“调用堆栈”窗口中激活PspUnreadyThread函数相应的堆栈项,然后

按F10单步调试,直到返回PspSe1ectNextThread函数并将线程状态修改为Run

ning。再从快速监视对话框中查看“*PspCurrentThread”表达式的值,观测当

前占用解决器的线程的情况。其中State域的值为2(Running),双向链表项State

ListEntry的Next和Prev指针的值都为0,说明控制台派遣线程己经处在运营

状态了。接下来,会将该线程的上下文从线程控制块(TCB)复制到解决器的各个寄存器

中,解决器就可以从该线程上次停止运营的位置继续运营

5.线程由运营状态进入阻塞状态.

(1)按F5继续执行,在PspWait函数中的断点处中断。在快速监视对话框

中查看“*PspCurrentThread”表达式的值,观测当前占用解决器的线程的情况。

其中State域的值为2(Running),双向链表项StateListEntry的Next和P

rev指针的值都为0,说明这个线程仍然处在运营状态;StartAddr域的值为lopC

onso1eDispatchThread,说明这个线程就是控制台派遣线程。

(2)按F10单步调试,直到左侧的黄色箭头指向代码第248行。再从快速监视对话

框中查看"*PspCurrentThread"表达式的值。其中State域的值为3(Wai

ting),双向链表项StateListEntry的Next和Prev指针的值都不为0,说明控

制台派遣线程已经处在阻塞状态了,并在某个同步对象的等待队列中。第248行代码可

以触发线程调度功能,会中断执行当前已经处在阻塞状态的控制台派遣线程,并将解决

器上下文保存到该线程的线程控制块。

2.2为线程增长挂起状态的实现

(给出实现方法的简要描述、源代码、测试和结果等)

1.为线程增长挂起状态

(1)删除之前添加的所有断点。

(2)按F5启动调试。

(3)待EOS启动完毕,在EOS控制台中输入命令“loop”后按回车。此时可以看到

loop线程的执行计数在不断增长,说明loop线程正在执行。记录下1oop线程的ID。

(4)按Ctr1+F2切换到控制台2,输入命令"suspend31"(假如loop线

程的ID是31)后按回车。命令执行成功的结果如下图所示。

(5)按Ct门+1切换回控制台1,可以看到由于1oop线程已经成功被挂起,其执行计

数已经停止增长了。此时占用解决器的是EOS中的空闲线程。

2.完毕Resume原语后,可以先使用suspend命令挂起1oop线程,然后在控制台2

中输入命令"Resume31"(假如1。op线程的ID是31)后按回车。命令执行成功

的结果如下图所示。假如切换回控制台1后,发现loop线程的执行计数恢复增长就说

明Resume原语可以正常工作。

OSLabPC-licrosoftVirtualPC2007,|-|x|

ActionEditCDFloppyHelp

COMSOLE-Z(PressCtrl+F1^F8toswitchconsoleuindow...)

UelcometoEOSshell

>suspend31

Suspendthread(31)success.

>resume31

Resumethread(31)success.

设计代码

STATUS

PsResumThread(

INHANDLEhThread

°)

(

STATUSStatus;

BOOLIntState;

PTHREADThread;

Status=ObRefObjectByHandie(hThread,PspThreadType,

(PVOID*)&Thread);

-if(EOS_SUCCESS(Status)){

“IntState=KeEnablelnterrupts(FALSE);〃关中断

。if(Zero==Thread->State){

sListRemoveEntry(&Thread->StateListEntry);

ee66PspReadyThread(Thread);

。“oPspThreadSchedu1e();

““Status=STATUS_SUCCESS;

}e1se{

Status=STATUS_NOT_SUPPORTED;

600}

KeEnab1elnterrupts(IntState);//开中断

。ObDerefObject(Thread);

0}

returnStatus;

}

1.一方面调用ListRemoveEntry函数将线程从挂起线程队列中移除。

2.然后调用PspReadyThread函数将线程恢复为就绪状态。

3.最后调用PspThreadSchedule宏函数执行线程调度,让刚刚恢复的线程有机会执

行。

3其他需要说明的问题

€实验二进程的同步(7分)

1实验目的和规定

目的:理解进程同步的原理和意义,掌握信号量的实现方法和应用。

规定:

(1)使用EOS的信号量,实现生产者-消费者问题;

(2)跟踪调试EOS信号量的工作过程,分析EOS信号量实现的源代码;

(3)修改EOS信号量的实现代码,使之支持等待超时唤醒和批量释放功能。

2完毕的实验内容

2.1使用EOS的信号量实现生产者-消费者问题

(简要说明使用EOS的信号量解决生产者一消费者问题的实现方法;给出在本部分实脸

过程中完毕的重要工作,涉及调试、跟踪、测试与思考等)

EOS使用CreateThread函数创建线程,使用CreateMutex^Creates

emaphore创建信号量。WaitForSingleObject与ReieaseMutex>Re1ea

seSemaphore函数相称于P、V原语。

设计思绪和流程图:

按照下面的环节查看生产者-消费者同步执行的过程:

1.使用pc.c文献中的源代码,替换之前创建的EOS应用程序项目中EOSApp.

c文献内的源代码。

2.按F7生成修改后的EOS应用程序项目。

3.按F5启动调试。OSLab会一方面弹出一个调试异常对话框。

4.在调试异常对话框中选择“否”,继续执行。

5.立即激活虚拟机窗口查看生产者一消费者同步执行的过程,如图(3-2o

6.待应用程序执行完毕后,结束本次调试。

1.Mutex、Empty、Fu11三个信号量的初始值分别为1、10、0,当存在一个生产者线

程访问缓冲池时,一方面对Empty减1,假如大于0,则说明尚有剩余缓冲区可以让生产

者放入产品,否则生产者线程进入等待队列;再对Mutex减1,假如大于等于0,则说

明没有线程占用缓冲池,否则生产者线程进入等待队列。生产完产品后,对Mutex加

1,解除封锁;再对Full加1,说明生产了一个产品占用了一个缓冲区。消费者线程同理,

对信号量的操作顺序与生产者线程相反。不能对这三个同步对象的操作改变顺序,否则

也许导致死锁。

2.由于临界资源的访问限制,程序中限定了缓冲池的大小为10,只有缓冲池有空余时

生产者才干向里边放产品,同时只有缓冲池有产品时消费者才干向外取东西。当生产者

生产了13号产品后,共生产了从0到13的14个产品,但是只消费了从0至IJ3的4个产

品,所以缓冲池中的10个缓冲区就都被占用了,所以不能继续生产14号产品,而要等到

消费者消费掉一个产品后,缓冲池有空余位置,才干继续生产14号产品。当生产者线程

生产了13号产品后,此时FulI信号量的值为10,而Empty信号量的值为0,此时若生产

者线程要再生产一个产品,先对Empty减1,此时Empty值小于零,生产者线程进入等

待队列;而此时若有一个消费者线程要消费一个产品,先对Full减1,此时Full值为9,

大于0,假如没有线程占用缓冲池,消费者可以消费一个产品。这样,生产者和消费者就

能实现同步过程了。

2.2EOS信号量工作过程的跟踪与源代码分析

(分析EOS信号量实现的核心源代码,简要阐述其实现方法;给出在本部分实验过程中

完毕的重要工作,涉及调试、跟踪与思考等)

EOS的P、V原语实现是PsWaitForSemaphore、PsReieaseSemaphor

e,这两个函数使用KeEnableInterrupts开关中断来实现原语操作。

PsWaitForSemaphore流程图:

PsRe1easeSemaphore函数的流程图:

2.3支持等待超时唤醒和批量释放功能的EOS信号量实现

(给出实现方法的简要描述、源代码、测试和结果等)

修改PsWaitForSemaphore函数,先用计数值和0比较,当计数值大于

0时,将计数值减1后直接返回成功;当计数值等于0时,调用PspWait函数阻塞

线程的执行(将参数MiHiseconds做为PspWait函数的第二个参数,并使用Ps

pWait函数的返回值做为返回值)。

修改PsWaitForSemaphore函数如下添加支持超时。

STATUS

PsWaitForSemaphore(

INPSEMAPHORESemaphore,

INULONGMil1iseconds

)

BOOLIntState;

ASSERT(KeGetIntNestingO0);

IntState=KeEnablelnterrupts(FALSE);

STATUSret;

if(Semaphore->Count>0){

Semaphore->Count-

ret=STATUS_SUCCESS;

}else{

ret=PspWait(&Semaphore—>WaitListHead9Millisecond

s);

}

KeEnableinterrupts(IntState);/

returnret;

)

修改PsReleaseSemaphore函数如下添加批量释放支持。

STATUS

PsReleaseSemaphore(

INPSEMAPHORESemaphore,

4NLONGRe1easeCount,

oOUTPLONGPreviousCount

6)

(

oSTATUSStatus;

B0OLIntState;

IntState=KeEnablelnterrupts(FALSE);

if(Semaphore—>Count+ReleaseCount>Semaphore->Maximum

Count){

?Status=STATUS_SEMAPHORE_LIMIT_EXCEEDED;

)else(

if(NULL!=PreviousCount){

o*PreviousCount=Semaphore->Count;

00)

fi6inti;

for(i=ReleaseCount;i—;){

。Semaphore->Count++;

gif(Semaphore—>Count<=0){

。PspWakeThread(&Semaphore->WaitListHead,

STATUS_SUCCESS);

do}

gPspThreadSchedule();

Status=STATUS_SUCCESS;

。}

KeEnablelnterrupts(IntState);

returnStatus;

3其他需要说明的问题

实验三时间片轮转调度(5分)

1实验目的和规定

目的:理解进程(线程)调度的执行时机和过程,掌握调度程序实现的基本方法。

规定:

(1)跟踪调试EOS的线程调度程序,分析EOS基于优先级的抢占式调度的源代码;

(2)修改EOS的调度程序,添加时间片轮转调度。

2完毕的实验内容

2.1EOS基于优先级的抢占式调度工作过程的跟踪与源代码分析

(分析E。S基于优先级的抢占式调度的核心源代码,简要阐述其实现方法;给出在本

部分实脸过程中完毕的重要工作,涉及调试、跟踪与思考等)

实验使用EOS提供的rr命令观测时间片的轮转。

1.准备实验

(1)启动OSLab»

(2)新建一个EOSKernel项目。

2.阅读控制台命令“rr”相关的源代码

(1)按F7生成在本实验3.1中创建的EOSKerne1项目。

(2)按F5启动调试。

(3)待EOS启动完毕,在E0S控制台中输入命令“rr”后按回车。

OSLabPC-licrosoftVirtualPC如07-|D|x|

ActionEditCDFloppyHelp

CONSOLE-1(PressCtrl+F1~F8toswitchconsolewindow...)

Thread0(8):49740

3.调试线程调度程序

a)调试当前线程不被抢先的情况

(1)结束之前的调试。

(2)在ke/sysproc.c文献的ThreadFunction函数中,调用fprintf函数的代码行

(第680行)添加一个断点。

(3)按F5启动调试。

(4)待EOS启动完毕,在EOS控制台中输入命令“rr”后按回车。“rr”命令开始执行

后,会在断点处中断。

(5)查看ThreadFunction函数中变量pThreadParameter->Y的值应当为0,说明正在

调试的是第0个新建的线程。

(6)激活虚拟机窗口,可以看到第0个新建的线程还没有在控制台中输出任何内容,因素

是fprintf函数还没有执行。

(7)激活OSLab窗口后按F5使第0个新建的线程继续执行,又会在断点处中断。再

次激活虚拟机窗口,可以看到第0个新建的线程已经在控制台中输出了第一轮循环的内

容。可以多按几次F5查看每轮循环输出的内容。

b)调试当前线程被抢先的情况

(1)选择“调试”菜单中的“删除所有断点”,删除之前添加的所有断点。

(2)在ps/sched.c文献的PspSelectNextThread函数的第395行添加一个断

点。

(3)按F5继续执行,激活虚拟机窗口,可看到第0个新建的线程正在执行。

(4)在虚拟机窗口中按下一次空格键,EOS会在之前添加的断点处中断。

(5)在“监视”窗口中查看就绪位图的值为1,说明此时在优先级为24的就绪队列中

存在就绪线程。在“监视”窗口中添加表达式“ListGetCount(&PspReadyLi

stHeads[24])”,其值为1,说明优先级为24的就绪队列中只有一个就绪线程。扫描

就绪位图后获得的最高优先级的值HighestPri。rity也就应当是24。

(6)按Fl0单步调试一次,执行的语句会将当前正在执行的第0个新建的线程,放入优

先级为8的就绪队列的队首。“监视”窗口中显示的优先级为8的就绪队列中的线程数

量就会增长1,变为20。

(7)继续按F10单步调试,直到在第444行中断执行,注意观测线程调度执行的每一

个环节。此时,正在执行的第0个新建的线程已经进入了“就绪”状态,让出了CPU。

线程调度程序接下来的工作就是选择优先级最高的非空就绪队列的队首线程作为当前运

营线程,也就是让优先级为24的线程在CPU上执行。

(8)按F10单步调试一次,当前线程PspCurrentThread指向了优先级为24

的线程。可以在“快速监视”窗口中查看表达式“*PspCurrentThread”的值,注意

线程控制块中StartAddr域的值为lopConso1eDispatchThread函数(在文

献i。/conso1e.c中定义),说明这个优先级为24的线程是控制台派遣线程。

(9)继续按F10单步调试,直到在PspSe1ectNextThread函数返回前(第465行)

中断执行,注意观测线程调度执行的每一个环节。此时,优先级为24的线程己经进入了

“运营”状态,在中断返回后,就可以开始执行了。在“监视”

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论