第一范文网 - 专业文章范例文档资料分享平台

操作系统课程设计实验报告proj1

来源:用户分享 时间:2025/5/28 18:04:54 本文由loading 分享 下载这篇文档手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:xxxxxxx或QQ:xxxxxx 处理(尽可能给您提供完整文档),感谢您的支持与谅解。

到关于该线程的信息(线程: 当前线程, 唤醒时间: 当前时间+x), 该线程设定唤醒时间并阻塞,并调用sleep操作使当前线程挂起, 放入队列中。在时钟回调函数中(大约每500个时钟间隔调用一次) 有一次中断,中断时则依次检查队列中的每个对象,将队列中此时应当唤醒的进程加入就绪队列。如果唤醒时间大于当前时间, 则将该对象移出队列并执行wake操作将相应线程唤醒。

(3)Waiter()是一个用来管理和存储多个Kthread及其唤醒时间的内部类,属性分别为该Kthread与其唤醒时刻waketime。

2.3.3关键点与难点

线程调用waitUntil方法之后会终止,该线程设定唤醒时间并阻塞,直到传入的时间之后才可以执行。线程只是放入就绪队列,等待分配。可以使用一个线程队列,但是不能产生额外的线程。

Timer每过500个clock ticks会产生一个timeInterrupt。timeInterupt时,会运行handle()线程,将handler线程功能设置为将队列中此时应当唤醒的进程加入就绪队列。

2.3.4实现代码

class Waiter {

private LinkedList waitlist; // 存放线程以及唤醒时间 }

9

Waiter(long wakeTime, Kthread thread) { }

private long wakeTime; // 唤醒时间

this.wakeTime = wakeTime; this.thread = thread;

private Kthread thread; // 等待的线程 }

public void waitUntil(long x) {

}

// 系统关中断

oolean intStatus = Machine.interrupt().disable();

// for now, cheat just to get something working (busy waiting is // 确定唤醒的时间

long wakeTime = Machine.timer().getTime() + x;

Waiter waiter = new Waiter(wakeTime, Kthread.currentThread()); // 将线程加入到等待队列上 waitlist.add(waiter);

System.out.println(“线程:” + Kthread.currentThread().getName()

+ “\\t休眠时间:” + Machine.timer().getTime() + “\\t下次唤醒+ wakeTime);// 当前线程设定唤醒时间并阻塞,挂起

bad)

时间:”

Kthread.sleep();// 开中断

Machine.interrupt().restore(intStatus);

2.4 Task 1.4条件变量实现同步消息 2.4.1题目要求

使用条件变量来实现一个字长信息的发送和接收同步。使用void speak(int word) 和int listen()函数来实现通讯(Communicator)类的通讯操作。Speak函数具有原子性,在相同地Communicator类中等待listen函数被调用,然后将此字发生给listen函数。一旦传送完毕,两个函数都返回(listen函数返回此字)。

2.4.2题目分析与实现方案

解决方案要满足使用同一个通讯对象实例中多个speaker和listener能够相互通讯。(注意:这种情况等于0字长的缓冲区;既然缓冲区没用空间,那么需要生产者和消费者直接进行交互,要求他们相互等待)。每一个通讯实例只能使用一个lock类,如果使用多于一个lock类,会将事情复杂化。

10

每个Communicator拥有的锁(保证操作的原子性) 和与该锁联系的两个条件变量用于保证speaker和listener间的同步。在speak函数中, 首先检查是否已经有speaker在等待(speaknum>0) 或无listener等待,满足这两种情况就挂起。 若不满足,则设置变量, 准备数据并唤醒一个listener。

在listen函数中, 增加一个listener后, 首先, 然后这个问题其实是一个缓冲区长度为0的生产者/消费者问题。

Speak():先获得锁,然后进行判断,如果没有听者等待,就要把说者放入队列然后睡眠。如果有听者等待,就要唤醒一个听者,然后传递消息,最后释放锁。

Listen():先获得锁,然后进行判断尝试唤醒speaker,如果没有说者等待,就要把听者放入队列然后睡眠。如果有说者等待,就要唤醒一个说者,将自己挂起以等待speaker准备好数据再将自己唤醒,然后传递消息,最后释放锁。

2.4.3关键点与难点

当有多个speaker和listener时,它们也只能是一对一的, 即一个speaker只能将数据发送到一个listener, 一个listener也只能接收来自一个speaker的数据, 其余的speakers和listeners都需要等待。多个speaker阻塞时需要保存每一个speaker的word,阻塞的speaker挂在Condition对象的Queue队列上。因为无缓冲区,listener唤醒说者后要先挂起,消息在speaker准备好后才传递。

2.4.4实现代码

11

public class Communicator {

private Lock lock; // 互斥锁 private int word = 0;

private static int speakercount = 0; // 说者数量 private static int listenercount = 0; // 听者数量

LinkedList Wordqueue = new LinkedList();// 保存说Condition2 speaker;// 说者条件变量 Condition2 listener;// 听者条件变量 public Communicator() { }

lock = new Lock();

speaker = new Condition2(lock); listener = new Condition2(lock);

者话语的队列

/*先获得锁,然后进行判断,如果没有听者等待,就要把说者放入队列然后睡眠。 如果有听者等待,就要唤醒一个听者,然后传递消息,最后释放锁*/

public void speak(int word) {// 系统关中断 oolean intStatus = Machine.interrupt().disable();

// 拿到锁

lock.acquire();// 没有听者,说者睡眠,队列存储说者的话 if (listenercount == 0) {

speakercount++;

Wordqueue.offer(word);

speaker.sleep();// 尝试唤醒听者 listener.wake();// 说者队列人数减一 speakercount--;

} else {// 准备消息,唤醒听者 Wordqueue.offer(word);

listener.wake(); }// 释放锁

lock.release();// 系统开中断

Machine.interrupt().restore(intStatus);

System.out.println(Kthread.currentThread().getName() + “ 发出信

息 “ + word); return;

}

oolean intStatus = Machine.interrupt().disable();// 获得锁 lock.acquire();

if (speakercount != 0) {

speaker.wake();

12

public int listen() {// 系统关中断

搜索更多关于: 操作系统课程设计实验报告proj1 的文档
操作系统课程设计实验报告proj1.doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.diyifanwen.net/c71dsf24tou570pl9t1ue_3.html(转载请注明文章来源)
热门推荐
Copyright © 2012-2023 第一范文网 版权所有 免责声明 | 联系我们
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:xxxxxx 邮箱:xxxxxx@qq.com
渝ICP备2023013149号
Top