ImageVerifierCode 换一换
格式:DOCX , 页数:28 ,大小:236.97KB ,
资源ID:3139308      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bingdoc.com/d-3139308.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(山东大学操作系统个人报告软件八班杨环.docx)为本站会员(b****1)主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(发送邮件至service@bingdoc.com或直接QQ联系客服),我们立即给予删除!

山东大学操作系统个人报告软件八班杨环.docx

1、山东大学操作系统个人报告软件八班杨环操作系统课程设计个人报告201100300268- 杨环第一部分 建立线程系统: 1TASK1.1 1TASK1.2 3TASK1.3 5TASK1.4 6TASK2 8TASK2.1 10TASK2.2 13TASK2.3 17总结 19第一部分 建立线程系统 在解决phrase1之前,先研究代码TASK1.1 任务 实现KThread.join() 当前线程a在运行,执行b.join(),则a阻塞,直到线程b结束,a继续执行。几个重要的方法禁止中断机制的实现Interrupt类有一个boolean型变量enabled,其值true时,表示允许中断,fal

2、se不允许中断。一般方法不希望执行过程中被中断就在方法开始处添加boolean intStatus = Machine.interrupt().disable();结束处添加 Machine.interrupt().restore(intStatus);关中断disable()只有一句return setStatus(false)设置interrupt状态为false,并且以前的状态保存在intstatus,开中断处restore(intStatus)就是将enabled值设为intStatus;这样就实现了开关中断的过程。setStatus(boolean status)方法还模拟了系统内的

3、时间“前进”,当interrupt的状态从不可行变为可行,即关中断到开中断,模仿时间前进:tick(true)。KThread.sleep()当前线程没有结束,就将其状态设为”阻塞”,通过调度器类从就绪队列中选择下一个执行的进程,选择过程又与调度器种类与策略有关。Lib.assertTrue(s) Lib里面是一些写好了的函数库,Lib.assertTrue如果括号内语句为false,则抛出一个异常.抽象类threadqueue有waitForAccess(KThread thread)和acquire(KThread thread)两个抽象方法,threadqueue我是这样理解的:一个线程

4、队列等待着某个资源,所以每个临界资源可以用当前等待着的线程队列来指代,waitForAccess(t)说明t也加入到该资源的等待队列了,acquire(t)则表示 t已经得到这个资源了。抽象类Scheduler里有个方法newThreadQueue(boolean transferPriority)该方法构造了一个线程队列,调度器在线程等待队列 选择 下一个可获得资源访问权限时需要使用一个参数,姑且称为“优先级”,优先级高的可得到资源,这会导致饥饿,如cpu也是一个资源,就绪队列等待cpu资源,如果ABC三个线程优先级分别是321,B等待着C所占有的一个资源,C只有运行结束才释放这个B等代着的

5、资源,C当前拥有cpu,当根据普通优先级调度方法它无法获得CPU,进而B也无法执行,所以就约定当前获得CPU线程优先级可以直接设为不小于等待队列中最大的优先级,以便于优先级小的线程快点结束释放其拥有的资源代码 在KThread.java 中: private ThreadQueue joinQueue = null; 每个kthread对象都有自己的joinQueue,由由对本线程调用join方法的其他线程对象构成,可“捐赠”优先级private boolean Joined = false;布尔形变量joined,判断本线程是否被其他线程调用过join方法,完善finish()方法时会用到p

6、ublic boolean IsAlive() if(this.status=statusNew|status=statusReady| status=statusRunning|status=statusBlocked) return true; else return false;一个简单的判断线程是否结束的方法,Kthread有五种状态,只要状态不为finished,就返回true public void join() Lib.debug(dbgThread, Joining to thread: + toString(); Lib.assertTrue(this != currentT

7、hread); if (this.status = statusFinished) return; boolean intStatus = Machine.interrupt().disable();/关中断 this.hasBeenJoined = true;/设置join标志,在finish方法中使用 if (this.joinQueue = null) this.joinQueue = ThreadedKernel.scheduler.newThreadQueue(true); this.joinQueue.acquire(this);/新建一个可转让优先级的线程队列joinqueue,

8、调用join方法的进程直接拥有该队列的最高优先级 this.joinQueue.waitForAccess(KThread.currentThread();/currentThread()等待在队列上 KThread.sleep(); Machine.interrupt().restore(intStatus);public static void finish() Machine.autoGrader().finishingCurrentThread(); if (currentThread.Joined) currentThread.joinQueue.nextThread().ready

9、();/currentThread结束前检查Joined标志,有等待线程的就选择一个加入就绪队列 Lib.assertTrue(toBeDestroyed = null); toBeDestroyed = currentThread; currentThread.status = statusFinished; sleep(); /执行就绪队列下个线程 在join类测试代码里创建AThread和Bthread两个线程,AThread循环打印“AThread循环第.次”语句,Bthread开始打印“B_thread 就绪”语句,中间执行AThread。Join()方法,最后打印“B_thread

10、执行结束”语句。根据结果可以验证基本实现了join()方法TASK1.2用允许/屏蔽中断的方法实现条件变量Condition类中已有利用信号量实现的条件变量,我们需要实现不依靠信号变量的实现,Condition最重要的部分是对Lock类的使用,Lock可被视为线程运行必需的“资源”,拥有lock资源的线程才能访问一些临界资源,即不能被多线程同时访问或修改的资源,lock对象拥有一个ThreadQueue waitQueue,且优先级转让标志为true,这意味着获得lock的线程不会因为优先级问题失去该lock。Lock.release()方法让当前拥有锁的线程放弃锁,通过lockHolder

11、= waitQueue.nextThread()来实现。Lock.acquire()方法要求得到锁,若要求时锁没被其他线程拥有,则调用acquire()方法的线程直接得到锁,否则将调用acquire()方法的线程加到lock对象的waitQueue中等待。Condition2类也有一个waitQueue,用来存放等待在条件变量上的线程,sleep方法的核心是在 conditionLock.release(); KThread.sleep();/ conditionLock.acquire();过程中,线程调用Condition2.sleep()方法后,失去锁,阻塞在conditionlock这

12、个资源上,要acquire()才能结束sleep()方法。condition.Wake()只能被拥有conditionLock资源的线程执行,故可实现一个线程等待条件变量的条件成立而挂起;另一个线程使条件成立;互斥锁的使用为了防止竞争,与条件变量结合在一起。public class Condition2 public Condition2(Lock conditionLock) this.conditionLock = conditionLock; waitQueue = new LinkedList(); public void sleep() Lib.assertTrue(conditio

13、nLock.isHeldByCurrentThread(); boolean intStatus = Machine.interrupt().disable();/关中断 waitQueue.add(KThread.currentThread();/当前线程被添加到条件变量的等待队列上 conditionLock.release();/释放锁 KThread.sleep();/线程状态设为阻塞 conditionLock.acquire();/要求锁,这是线程阻塞的原因 Machine.interrupt().restore(intStatus);/开中断 public void wake()

14、 Lib.assertTrue(conditionLock.isHeldByCurrentThread();/只能被拥有conditionLock资源的线程执行 boolean intStatus = Machine.interrupt().disable();/关中断 waitQueue.remove().ready();/直接将waitQueue里的线程移出并将其状态设为ready Machine.interrupt().restore(intStatus);/开中断 public void wakeAll() Lib.assertTrue(conditionLock.isHeldByCu

15、rrentThread(); while (!waitQueue.isEmpty() wake(); /利用while循环将waitqueue里所有线程“唤醒” private Lock conditionLock; private LinkedList waitQueue;在Condition2测试方法里创建共有条件变量c2test,一个临界资源count和三个线程,thread1,thread2,thread3,初始化三个线程后thread1,thread2调用c2test.sleep()后开始“睡眠”,thread3调用c2test.wakeAll()唤醒所有线程,thread1,the

16、ad2开始交替访问临界资源count并更改其“余额”数值。根据结果可以验证基本实现了join()方法TASK1.3 完成Alarm类中的waitUntil方法Time类模拟时钟中断。Nachos虚拟机可以如同实际的硬件一样,每隔一定的时间会发生一次时钟中断,scheduleInterrupt()方法里有句delay += Lib.random(delay/10) - (delay/20);相当于设置下次中断的时间增加了随机因子,因为对nachos主控模块里的线程切换没有研究很深,暂且不提。每次的时钟中断都会使用时钟中断处理程序。Alarm类有alarmqueue用来保存睡眠的线程,组成对象为A

17、larmThread为了给每个线程绑定“醒来时间”,创建了一个新的对象AlarmThreadKThread waitThread; /private Condition timecondition; private long wakeTime;/醒来时间同时重写中断处理程序,从alarmqueue中选择一个alarmthread,比较系统当前时间和waketime,系统时间是通过timer().getTime()得到的,当前时间大于waketime,则 在时钟回调函数中 (大约每500个时钟间隔调用一次) 则依次检查队列中的每个三元组.元组移出队列并对元组中相应线程状态值设为ready();p

18、ublic void waitUntil(long x) boolean intStatus = Machine.interrupt().disable();/关中断 long wakeTime = Machine.timer().getTime() + x;/设置唤醒时间 Lock lock=new Lock(); Condition con=new Condition(lock); AlarmThread thread = new AlarmThread(KThread.currentThread(), wakeTime,con);/调用waitutil方法线程被装进alarmthread

19、 alarmqueue.add(thread); KThread.sleep(); Machine.interrupt().restore(intStatus);/开中断在测试方法里创建5个线程,依次“睡眠”20000ticks,线程醒来后各自打印出睡眠开始时间,要求睡眠时间,醒来时间,以及实际睡眠时间。可以发现线程的实际睡眠时间并不等于要求的睡眠时间。 TASK1.4 Communicator类很像一个管程,它利用条件变量实现多个进程之间的同步。用条件变量实现Communicator类中的speaker()和listen()函数一个锁lock两个条件变量speaker(lock),liste

20、ner(lock)用来用来控制听说动作,Message变量用来存储speaker的消息,每个Communicator有一个锁 lock(保证操作的原子性) 和与该锁联系的两个条件变量用于保证speaker和listener间的同步. 在speak函数中, 首先检查若已经有一个speaker在等待(message变量) 或无listener等待, 则挂起. 否则设置message变量, 准备数据并唤醒一个listener. 在listen函数中, 增加一个listener后, 若speaker数目非零且listener数目为1(及恰好可以配对)首先唤醒speaker, 然后将自己挂起以等待 sp

21、eaker准备好数据再将自己唤醒. 这个问题其实是一个缓冲区长度为0的生产者/消费者问题。Speaker方法 listener方法 public class Communicator public Communicator() lock=new Lock(); speaker=new Condition(lock); listener=new Condition(lock); speakersize=0; listenersize=0; public void speak(int word) lock.acquire(); while(speakersize!=0) speaker.sleep

22、(); this.Message=word; speakersize+; while(listenersize=0) speaker.sleep(); listener.wake(); speakersize-; speaker.wake(); lock.release(); public int listen() /int myMessage=0; lock.acquire(); listenersize+; if(listenersize=1&speakersize!=0) speaker.wake(); /speaker.wake(); listener.sleep(); /pair.w

23、ake(); int myMessage = this.Message; listenersize-; lock.release(); return myMessage; int speakersize,listenersize; int Message; Condition speaker,listener; private Lock lock;TASK2本阶段需要测试真正意义上的程序 (由MIPS-C编译器编译出的二进制指令). 使用的内核类是nachos.userprog.UserKernel (继承自nachos.threads.ThreadedKernel), 线程类是userpro

24、g.UThread (继承自threads.KThread)。为安装mips交叉编译器,本任务开发环境变为ubuntu 12.04提供linux环境,配置好jdk及安装好eclipse后,安装提供的binutils-2.24,经测试可执行由MIPS-C编译器编译出的二进制指令(coff).一些我对nachos执行coff文件过程的理解,Coff文件载入后被转换为一个 machine.Coff 类型的对象,它包括若干个段。每个段是一个machine.CoffSection类型的对象,每个CoffSection又包括若干个页page。Coff的这种格式决定了我们在载入它的过程。系统提供了页表pag

25、eTable,它以虚拟页号为下标, 其中每一项是一个machine.TranslationEntry类型的对象。TranslationEntry参数 ppn物理页号 vpn虚拟页号 valid是否有效 readOnly是否只读 used是否被使用过 dirty是否“脏” 要执行test文件夹里的coff文件,首先给它分配一个Uthread(继承自KThread),因此可以通过调用父类fork(),join()等已实现的方法,而在一个UThread里面得到一个新的UThread。UThread运行时候的工作public UThread(UserProcess process) super();/

26、继承父类构造方法等 setTarget(new Runnable() public void run() runProgram(); ); this.process = process; private void runProgram() process.initRegisters(); process.restoreState(); Machine.processor().run(); Lib.assertNotReached(); 先给它实现一个运行的Runnable接口,再绑定到一个process上,RunProgram()方法第一步,process.initRegisters();初始

27、化寄存器。第二步process.restoreState();要将状态调入,然后开始运行Process了。Userkernel继承 ThreadedKernel,初始化如下,首先运行console,然后就要为processor(处理器)提供一个异常处理机制,得到所有物理页数目public void initialize(String args) super.initialize(args); console = new SynchConsole(Machine.console(); Machine.processor().setExceptionHandler(new Runnable() p

28、ublic void run() exceptionHandler(); ); int totalPages = Machine.processor().getNumPhysPages(); 中断处理函数public void exceptionHandler() Lib.assertTrue(KThread.currentThread() instanceof UThread); UserProcess process = (UThread) KThread.currentThread().process; int cause = Machine.processor().readRegist

29、er(Processor.regCause); process.handleException(cause); 当前的Thread里面的process设置成了函数的process,。然后从Processor的寄存器里面读取出导致exception的cause值,具体寄存器的使用没有深入研究。Userkernel的run()函数有这样指令UserProcess process = UserProcess.newUserProcess();/ Lib.assertTrue(process.execute(shellProgram, new String );大意是分配新进程,该进程载入coff文件

30、的名字,Process类execute()方法主要靠load方法载入coff文件,该方法也是我们在TASK2.2中需要实现的。TASK2.1Nachos以及linux操作系统里文件描述符是一个很方便的东西,它是进程用来在本地文件记录打开的文件的一个向int数值的映射,这种映射是一对一的,进程自己都有一张自己的文件记录表,大小不超过16,0和1固定给I/O使用,只剩下至多14个int型文件描述符,与线程类似,每个process拥有唯一的ProcessId,rootProcess的Id是0;private int handleHalt() if (this.processID != 0) return -1; /非rootProcess调用halt会无效 Machine.halt();/ return 0;/getUnusedFileDescriptor() 获取一个可用的文件描述符private int getUnusedFileDescriptor() throws NachosInternalException for (int i = 0; i this.openFiles.length; +

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2