山东大学计算机学院操作系统实验报告Word文件下载.docx

上传人:b****5 文档编号:16001570 上传时间:2022-11-17 格式:DOCX 页数:35 大小:31.34KB
下载 相关 举报
山东大学计算机学院操作系统实验报告Word文件下载.docx_第1页
第1页 / 共35页
山东大学计算机学院操作系统实验报告Word文件下载.docx_第2页
第2页 / 共35页
山东大学计算机学院操作系统实验报告Word文件下载.docx_第3页
第3页 / 共35页
山东大学计算机学院操作系统实验报告Word文件下载.docx_第4页
第4页 / 共35页
山东大学计算机学院操作系统实验报告Word文件下载.docx_第5页
第5页 / 共35页
点击查看更多>>
下载资源
资源描述

山东大学计算机学院操作系统实验报告Word文件下载.docx

《山东大学计算机学院操作系统实验报告Word文件下载.docx》由会员分享,可在线阅读,更多相关《山东大学计算机学院操作系统实验报告Word文件下载.docx(35页珍藏版)》请在冰豆网上搜索。

山东大学计算机学院操作系统实验报告Word文件下载.docx

Java

开发工具:

EclipseLuna

操作系统:

Ubuntu14.04

二Project1建立线程系统

Task1.1实现KThread.join()

1.要求

实现ImplementKThread.join()函数。

注意:

其它的线程不必调用join函数,但是如果它被调用的话,也只能被调用一次。

对join函数第二次调用的执行结果是不被定义的(即使第二次调用的线程与第一次调用的线程不同)。

2.分析

Join函数的作用即为等待某线程运行完毕.当前线程(唯一一个正在运行的线程)A调用另一个线程(处于就绪状态)B的join函数时(A和B在Nachos中均为KThread类型对象),A被挂起,直到B运行结束后,join函数返回,A才能继续运行。

3.方案

原KThread的join()中的Lib.assertTrue(this!

=currentThread)已经实现线程只能调用一次join()方法,根据要求,在调用join()方法时,让当前运行线程休眠,并将当前运行的线程加入到一个阻塞队列中。

在线程结束时,finish()函数循环唤醒所有被阻塞的线程。

4.实现代码

publicvoidjoin()

{

Lib.debug(dbgThread,"

Joiningtothread:

"

+toString());

Lib.assertTrue(this!

=currentThread);

booleanintStatus=Machine.interrupt().disable();

if(status!

=statusFinished)

waitForJoin.waitForAccess(currentThread);

KThread.sleep();

}

}

publicstaticvoidfinish()

Finishingthread:

+currentThread.toString());

Machine.interrupt().disable();

Machine.autoGrader().finishingCurrentThread();

Lib.assertTrue(toBeDestroyed==null);

toBeDestroyed=currentThread;

currentThread.status=statusFinished;

KThreadwaitThread;

while((waitThread=currentThread.waitForJoin.nextThread())!

=null)

waitThread.ready();

sleep();

Task1.2利用中断提供原子性,直接实现条件变量

通过利用中断有效和无效所提供的原子性实现条件变量。

我们已经提供类似的例子用例实现信号量。

你要按此提供类似的条件变量的实现,不能直接利用信号量来实现(你可以使用lock,虽然它间接地调用了信号量)。

在你完成时要提供条件变量的两种实现方法。

你的第二种条件变量实现要放在nachos.threads.Condition2中。

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

condition.sleep采用waiter.P()实现休眠(waitor是一个信号量)并将waitor放入信号量队列,在我们的实现中改成用KThread.sleep()实现休眠并将当前线程放入线程队列,并在sleep函数开始/结尾处屏蔽/允许中断以保证原子性。

condition.wake中从等待信号量队列中取出信号量并对其进行V操作实现唤醒,在我们的实现中改成从线程队列中取出线程用KThread.ready()实现唤醒(同样要在wake函数开始/结尾处屏蔽/允许中断)。

wakeall函数的实现依赖于wake().只需不断地wake直到队列为空为止.

privateThreadQueuewaitQueue=

ThreadedKernel.scheduler.newThreadQueue(false);

privatebooleanhasWaiter=false;

publicvoidsleep()

Lib.assertTrue(conditionLock.isHeldByCurrentThread());

waitQueue.waitForAccess(KThread.currentThread());

hasWaiter=true;

conditionLock.release();

KThread.sleep();

conditionLock.acquire();

Machine.interrupt().restore(intStatus);

publicvoidwake()

booleanintStatus=Machine.interrupt().disable();

KThreadthread=waitQueue.nextThread();

if(thread!

=null)

thread.ready();

else

hasWaiter=false;

Machine.interrupt().restore(intStatus);

publicvoidwakeAll()

Lib.assertTrue(conditionLock.isHeldByCurrentThread());

while(hasWaiter)

wake();

Task1.3实现waitUntil

通过实现waitUntil(intx)方法来完成Alarm类。

一个线程通过调用waitUntil函数来挂起它自己,直到now+x后才被唤醒。

在实时操作中,对线程是非常有用的,例如实现光标每秒的闪烁。

这里并不要求线程被唤醒后马上执行它,只是在它等待了指定时间后将它。

放入等待队列中。

不要通过产生任何附加的线程来实现waitUntil函数,你仅需要修改waitUntil函数和时间中断处理程序。

waitUntil函数并不仅限于一个线程使用,在任意时间,任意多的线程可以调用它来阻塞自己。

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

为了实现waitUntil,需要在Alarm类中实现一个内部类Waiter,保存等待的线程及其唤醒时间.在调用waitUntil(x)函数时,首先得到关于该线程的信息:

(线程:

当前线程,唤醒时间:

当前时间+x),然后构造新的Waiter对象,并调用sleep操作使当前线程挂起.在时钟回调函数中(大约每500个时钟间隔调用一次)则依次检查队列中的每个对象。

如果唤醒时间大于当前时间,则将该对象移出队列并执行wake操作将相应线程唤醒。

classWaiter

Waiter(longwakeTime,KThreadthread)

this.wakeTime=wakeTime;

this.thread=thread;

privatelongwakeTime;

privateKThreadthread;

publicvoidwaitUntil(longx)

longwakeTime=Machine.timer().getTime()+x;

Waiterwaiter=newWaiter(wakeTime,KThread.currentThread());

waitlist.add(waiter);

System.out.println(KThread.currentThread().getName()

+"

线程休眠,时间为:

"

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

应该在

"

+wakeTime+"

醒来."

);

KThread.sleep();

publicvoidtimerInterrupt()

Waiterwaiter;

for(inti=0;

i<

waitlist.size();

i++)

{

waiter=waitlist.remove();

if(waiter.wakeTime<

=Machine.timer().getTime())

{

System.out.println("

唤醒线程:

+waiter.thread.getName()+"

时间为:

+Machine.timer().getTime());

waiter.thread.ready();

//线程进入就绪状态

}

else

waitlist.add(waiter);

KThread.currentThread().yield();

privateLinkedList<

Waiter>

waitlist;

Task1.4用条件变量,不使用信号量,实现同步发送接收消息,speak,listen

使用条件变量来实现一个字长信息的发送和接收同步。

使用voidspeak(intword)和

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

当前位置:首页 > 表格模板 > 书信模板

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

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