山东大学操作系统课程设计代码分析及设计实现及测试报告Word下载.docx

上传人:b****8 文档编号:22742054 上传时间:2023-02-05 格式:DOCX 页数:59 大小:51.10KB
下载 相关 举报
山东大学操作系统课程设计代码分析及设计实现及测试报告Word下载.docx_第1页
第1页 / 共59页
山东大学操作系统课程设计代码分析及设计实现及测试报告Word下载.docx_第2页
第2页 / 共59页
山东大学操作系统课程设计代码分析及设计实现及测试报告Word下载.docx_第3页
第3页 / 共59页
山东大学操作系统课程设计代码分析及设计实现及测试报告Word下载.docx_第4页
第4页 / 共59页
山东大学操作系统课程设计代码分析及设计实现及测试报告Word下载.docx_第5页
第5页 / 共59页
点击查看更多>>
下载资源
资源描述

山东大学操作系统课程设计代码分析及设计实现及测试报告Word下载.docx

《山东大学操作系统课程设计代码分析及设计实现及测试报告Word下载.docx》由会员分享,可在线阅读,更多相关《山东大学操作系统课程设计代码分析及设计实现及测试报告Word下载.docx(59页珍藏版)》请在冰豆网上搜索。

山东大学操作系统课程设计代码分析及设计实现及测试报告Word下载.docx

privateThreadQueuejoinQueue=null;

privatebooleanJoined=false;

publicbooleanIsAlive(){

if(this.status==statusNew||status==statusReady||

status==statusRunning||status==statusBlocked)

returntrue;

elsereturnfalse;

}

publicvoidjoin(){

//

if(!

this.IsAlive())return;

while(IsAlive()){

//

this.joinQueue.acquire(this);

//

}

this.joinQueue.waitForAccess(KThread.currentThread());

KThread.sleep();

publicstaticvoidfinish(){

///

if(currentThread.Joined){

currentThread.joinQueue.nextThread().ready();

///

3.1.4测试代码及结果

创建AThread和Bthread两个线程,AThread循环打印“AThread循环第..次”语句,Bthread开始打印“B_thread就绪”语句,中间执行AThread。

Join()方法,最后打印“B_thread执行结束”语句。

测试代码:

packagenachos.threads;

importnachos.machine.*;

publicclassKThreadTest{

publicKThreadTest(){

publicstaticvoidsimpleJoinTest(){

KThreadA_thread=newKThread(newKThreadTest.A_thread(5));

KThreadB_thread=newKThread(newKThreadTest.B_thread(A_thread));

B_thread.fork();

B_thread.join();

publicstaticclassB_threadimplementsRunnable{

B_thread(KThreadjoinee){

this.joinee=joinee;

publicvoidrun(){

System.out.println("

B_thread就绪"

);

ForkingandjoiningA_thread..."

this.joinee.fork();

this.joinee.join();

B_thread执行结束"

privateKThreadjoinee;

publicstaticclassA_threadimplementsRunnable{

A_thread(intnum){

this.num=num;

A_thread就绪"

A_thread开始执行"

//Thisshouldjustkillsomecycles

for(inti=0;

i<

this.num;

++i){

A_thread循环第"

+i+"

次"

KThread.currentThread().yield();

A_thread执行结束"

privateintnum;

测试结果:

3.2Task1.2condition2类

3.2.1要求分析

threads.Lock类提供了锁以保证互斥.在临界代码区的两端执行Lock.acquire()和Lock.release()即可保证同时只有一个线程访问临界代码区.条件变量建立在锁之上,由threads.Condition实现,它是用来保证同步的工具.每一个条件变量拥有一个锁变量(该锁变量亦可被执行acquire和release操作,多个条件变量可共享同一个锁变量).当处于临界区内的拥有某锁Lock的当前线程对与锁Lock联系的条件变量执行sleep操作时,该线程失去锁L并被挂起.下一个等待锁L的线程获得锁L(这个过程由调度程序完成)并进入临界区.当拥有锁L的临界区内的当前线程对与锁L联系的条件变量执行wake操作时(通常调用wake之后紧接着就是Lock.release),等待在该条件变量上的至多一个被挂起的线程(由调用sleep引起)被重新唤醒并设置为就绪状态.若执行wakeall操作,则等待在该条件变量上的所有被挂起的线程都被唤醒.threads.condition已经实现了一个条件变量(采用信号量实现),题目要求用屏蔽/禁止中断的方法再实现一下条件变量(写在threads.condition2中)

3.2.2设计方案

为每个条件变量添加一个锁conditionLock和一个Kthread对象组成的等待队列waitqueue,condition.sleep将调用sleep()的线程加入到等待队列,释放锁,并阻塞,以便其他线程唤醒它,一旦’唤醒’立即要求锁,并在sleep函数开始/结尾处屏蔽/允许中断以保证原子性;

condition.wake中从等待队列中取出线程进行ready()实现唤醒,

(同样要在wake函数开始/结尾处屏蔽/允许中断),wakeall函数的实现依赖于wake.只需不断地wake直到队列为空为止.

3.2.3实现代码

见threads/condition2.java

privateLockconditionLock;

privateLinkedList<

KThread>

waitQueue;

publicvoidsleep(){

waitQueue.add(KThread.currentThread());

conditionLock.release();

conditionLock.acquire();

publicvoidwake(){

waitQueue.remove().ready();

3.2.4测试代码及结果

创建共有条件变量c2test,一个临界资源count和三个线程,thread1,thread2,thread3,初始化三个线程后thread1,thread2调用c2test.sleep()后开始“睡眠”,thread3调用c2test.wakeAll()唤醒所有线程,thread1,thead2开始交替访问临界资源count并更改其“余额”数值。

publicclassCondition2Test{

Lockcondlock=newLock();

Condition2c2test=newCondition2(condlock);

publicCondition2Test(){

publicvoidsimpleCondition2Test(){

System.out.println("

\n****Condition2Testisnowexecuting.****"

初始化账户余额为10000"

finalMyCountmyCount=newMyCount("

0000001"

10000);

//创建并发访问的账户

KThreadthread1=newKThread(newRunnable(){

newSaveThread("

张三"

myCount,2000);

张三goestosleep"

condlock.acquire();

c2test.sleep();

System.out.println("

张三reacquireslockwhenwoken."

condlock.release();

张三isawake!

!

"

myCount.save(2000,"

张三"

});

KThreadthread2=newKThread(newRunnable(){

李四"

李四goestosleep"

李四reacquireslockwhenwoken."

李四isawake!

李四"

KThreadthread3=newKThread(newRunnable(){

thread3Wakingupthethread"

condlock.acquire();

c2test.wakeAll();

condlock.release();

张三and李四wokeupbywakeAll"

thread1.fork();

thread2.fork();

thread3.fork();

thread1.join();

thread2.join();

thread3.join();

****Condition2Testfinished.****\n"

}

}

classSaveThreadextendsKThread{

privateStringname;

//操作人

privateMyCountmyCount;

//账户

privateintx;

//存款金额

SaveThread(Stringname,MyCountmyCount,intx){

this.name=name;

this.myCount=myCount;

this.x=x;

publicvoidrun(){

myCount.save(x,name);

classMyCount{

privateStringid;

//账号

privateintcash;

//账户余额

Locklock=newLock();

//账户锁

Condition2c2test=newCondition2(lock);

MyCount(Stringid,intcash){

this.id=id;

this.cash=cash;

publicvoidsave(intx,Stringname){

lock.acquire();

//获取锁

if(x>

0){

cash+=x;

//存款

System.out.println(name+"

存款"

+x+"

,当前余额为"

+cash);

lock.release();

//释放锁

3.3Task1.3alram类

3.3.1要求分析

一个线程调用waitUntil(x)后,它即被挂起.在当前时钟走过x个滴答后,该线程被重新唤醒.线程被唤醒后并不一定立即进入运行态,只要将其放入就绪队列中即可.另外,多个线程可以分别调用waitUntil函数。

3.3.2设计方案

于Alarm类有关的是machine.Timer类.它在大约每500个时钟滴答使调用回调函数(由Timer.setInterruptHandler函数设置).因此,Alarm类的构造函数中首先要设置该回调函数Alarm.timerInterrupt().

为了实现waitUntil,需要在Alarm类中实现一个队列Alarm.alarmQueue.队列中的每个项目是(线程,唤醒时间,相应条件变量)的三元组.在调用waitUntil(x)函数时,首先得到关于

以上三元组的信息:

(线程:

当前线程,唤醒时间:

当前时间+x,新分配的条件变量),然后将该元组放入队列中,并对条件变量sleep操作使当前线程挂起.在时钟回调函数中(大约每500个时钟间隔调用一次)则依次检查队列中的每个三元组.如果唤醒时间大于当前时间,则将元组移出队列并对元组中的条件变量执行wake操作将相应线程唤醒.

3.3.3实现代码

publicvoidtimerInterrupt(){

while(!

alarmqueue.isEmpty()&

&

(alarmqueue.peek().wakeTime<

=Machine.timer().getTime())){

AlarmThreadthread=alarmqueue.remove();

thread.waitThread.ready();

//

publicvoidwaitUntil(longx){

AlarmThreadthread=newAlarmThread(KThread.currentThread(),wakeTime,conditionlock);

alarmqueue.add(thread);

privateKThreadwaitThread;

privateConditiontimecondition;

privatelongwakeTime;

3.3.4测试代码及结果

创建5个线程,依次“睡眠”20000ticks,线程醒来后各自打印出睡眠开始时间,要求睡眠时间,醒来时间,以及实际睡眠时间。

测试代码:

publicstaticvoidselfTest(intnumOfTest){

Runnablea=newRunnable(){

AlarmTestThread();

};

for(inti=0;

i<

numOfTest;

i++){

intnumOfThreads=5;

print("

Creating"

+numOfThreads+"

numofthreads"

for(intj=0;

j<

numOfThreads;

j++){

KThreadthread=newKThread(a);

thread.setName("

thread"

thread.fork();

ThreadedKernel.alarm.waitUntil(30000000);

staticvoidAlarmTestThread(){

longsleepTime=20000;

longtimeBeforeSleep=Machine.timer().getTime();

ThreadedKernel.alarm.waitUntil(sleepTime);

longtimeAfterSleep=Machine.timer().getTime();

longactualSleepTime=timeAfterSleep-timeBeforeSleep;

print(KThread.currentThread().toString()+"

被要求在:

"

+timeBeforeSleep+"

睡眠"

+sleepTime+"

ticks"

被唤醒时间:

+Machine.timer().getTime()+"

要求睡眠时间:

:

ticks,实际睡眠时间:

+actualSleepTime);

publicstaticvoidprint(StringMessage){

System.out.println(Message);

3.4Task1.4communicator类

3.4.1要求分析

用条件变量实现Communicator类中的speaker()和listen()函数一个锁lock

两个条件变量speaker(lock),listener(lockw)用来用来控制听说动作。

3.4.2设计方案

每个Communicator有一个锁lock(保证操作的原子性)和与该锁联系的两个条件变量用于保证speaker和listener间的同步.在speak函数中,首先检查若已经有一个speaker在等待(message变量)或无listener等待,则挂起.否则设置message变量,准备数据并唤醒一个listener.在listen函数中,增加一个listener后,若speaker数目非零且listener数目为1(及恰好可以配对)首先唤醒speaker,然后将自己挂起以等待speaker准备好数据再将自己唤醒.这个问题其实是一个缓冲区长度为0的生产者/消费者问题。

3.4.3实现代码

Communicator.java

intspeakersize,listenersize;

intMessage;

Conditionspeaker,listener;

publicvoidspeak(intword){

//

while(speakersize!

=0)

{speaker.sleep();

this.Message=word;

speakersize++;

while(listenersize==0)

{speaker.sleep();

listener.wake();

speakersize--;

speaker.wake();

publicintlisten(){

listenersize++;

if(listenersize==1&

speakersize!

speaker.wake();

listener.sleep();

intmyMessage=this.Message;

listenersize--;

returnmyMessage;

3.4.4测试代码及结果

importjava.util.ArrayList;

importjava.util.Random;

publicclassCommunicatorTest{

publicCommunicatorTest(){

Message=1;

numOfSpeakers=5;

numOfListeners=5;

communicator=newCommunicator();

publicvoidcommTest(intnum){

\nCommunicatorTest开始"

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 自我管理与提升

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1