资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,二级,三级,四级,五级,2015/4/9,#,操作系统课程实验,TA:林璋玮 彭禹惟 冯善恒 李宏钊,课程计划,第5周:实验环境安装与搭建(part0),第67周:线程的休眠与唤醒(part1),第89周:优先级调度(part2),第1011周:线程锁、信号量与优先级继承(part3),第1214周:多级反馈队列调度(part4),实验一,.Non-busy,waiting,通过修改,pintos,的线程休眠函数来保证,pintos,不会在一个线程休眠时忙等待。,相关文件,pintos/src/devices目录:,timer.h,timer.c,pintos/src/threads目录:,thread.h,thread.c,需要阅读相关结构体以及函数。,Pintos,的机制,出于安全性等考虑,每隔一段时间操作系统必须获得,CPU,时间,进行进程调度等工作。而操作系统是通过中断来获得,CPU,时间,pintos,中操作系统中断频率为,、,thread,Pintos,中定义了一个,thread,的结构体用于存储线程的信息,(包括优先级,,,状态,等,),,位于,thread.h,。,其中,thread,有四个状态:,Thread,这个结构体贯穿整个实验。,thread,线程休眠,timer.c,中实现了线程休眠的函数,thread_sleep,这个函数作用是让线程休眠一定的时间。,ASSERT,作用是若语句不为真则退出。,线程休眠时必须保证中断是打开的。,线程休眠,thread_sleep,的实现原理是通过不断轮询检查经过时间是否达到,ticks,,若还没达到则调用,thread_yield,函数,达到了,ticks,就会结束休眠。,thread_yield,该函数会把当前线程放进,ready,队列,并调度下一个线程,线程调度时要保证中断关闭。,schedule,专门负责线程切换的函数,执行了以后会把当前线程放进队列里并调度出下一个线程。,线程休眠问题?,Thread_yield,函数只是把线程放进调度队列,然后切换线程,此时休眠线程状态是,ready,,在一个,tick,内依然有可能会被调度,继续消耗,cpu,时间,没有完全把时间让给别的进程,这样就违反了线程休眠的原则,造成了忙等待。,目标,通过重新设计,thread_sleep,函数让休眠线程不再占用,cpu,时间,只在每次,tick,中断把时间交给操作系统时再检查睡眠时间,,tick,内则把,cpu,时间让给别的线程。,解决办法,1.,重写,timer_sleep,函数,不是调用,thread_yield,而是调用,thread_block,函数把线程,block,了,这样在,unblock,之前该线程都不会被调度执行。,2,.Thread,结构体中新增成员变量,ticks_blocked,,记录线程剩余睡眠的时间,(,单位:,tick),。初始化为,0,,在,timer_sleep,函数中把,tick,赋值为睡眠时间。,解决办法,3.thread.c,中增加函数,checkInvoke,判断线程是否休眠完毕,(ticks_blocked,的值,),。,4,.,处理,timer,中断时(,timer_interrupt),遍历,所有线程,(,thread_for_each,,详细见代码,),并判断被,block,线程是否睡眠完毕,睡眠完毕则唤醒。,解决办法,完成上述步骤以后,大部分的,alarm,测试都通过了。但是,alarm_priority,依然还没通过。接下来介绍解决,alarm_priority,的知识。,list,List,的结构,,list,中存放的数据类型是,list_elem,,存放待执行线程靠的就是,list,。,Thread,与,list,有一个,list,变量,ready_list,专门存放待执行的线程,由于,list,存放的是,list_elem,类型,因此,thread,中有一个成员变量专门用于在,ready_list,中“排队”。,Thread,与,list,既然在,ready_list,中并不是,thread,而只是,thread,的一个成员,怎么通过,list,中的,elem,来访问对应线程的其他变量?,List,中已经提供了一个宏定义解决这个问题。,解决办法,alarm-priority,要求线程是根据优先级进行调度的,而,pintos,的基本实现是直接把线程放进,ready_list,尾部,,,是,FIFO,的调度方式。如果要通过这个测试就必须保证在,ready_list,中线程是有序的。,hints,:使用,list_insert_order,函数可以保证有序插入。,注意事项,1,.,先阅读源代码和测试的代码。把握线程的整体结构,以后做实验也会轻松一点。,2,.,调用函数前要看看该函数是否要求关闭或者打开中断。,3,.,修改前最好备份一下。,成功标志,make,check,中通过所有的,alarm,测试!,报告要求,1.,回答问题:,(,1,),.,为什么未经修改仍能通过一些测试,(alarm),?,(,2,).,为什么有些测试不能通过?,2,.,简单解说一下每个测试做了什么,并描述一下过程,3,.,关键代码截图,实验感想,
展开阅读全文