搜档网
当前位置:搜档网 › 操作系统课程设计实验报告proj1

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

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

操作系统课程设计报告

班级:

团队成员:

目录

目录 (2)

一、Nachos综述.......................................................................................... 错误!未定义书签。

二、实验要求:建立线程系统................................................................... 错误!未定义书签。

2.1Task 1.1实现KThread.join() (3)

2.1.1题目要求 (3)

2.1.2题目分析与实现方案 (3)

2.1.3关键点与难点 (4)

2.1.4实现代码 (4)

2.2 Task 1.2实现条件变量 (5)

2.2.1题目要求 (5)

2.2.2题目分析与实现方案 (5)

2.2.3关键点与难点 (6)

2.2.4实现代码 (7)

2.3 Task 1.3 完成Alarm类 (7)

2.3.1题目要求 (7)

2.3.2题目分析与实现方案 (8)

2.3.3关键点与难点 (9)

2.3.4实现代码 (9)

2.4 Task 1.4条件变量实现同步消息 (10)

2.4.1题目要求 (10)

2.4.2题目分析与实现方案 (10)

2.4.3关键点与难点 (11)

2.4.4实现代码 (11)

2.5 Task 1.5实现优先级调度 (13)

2.5.1题目要求 (13)

2.5.2题目分析与实现方案 (13)

2.5.3关键点与难点 (14)

2.5.4实现代码 (15)

2.6 Task 1.6条件变量解决过河问题 (16)

2.6.1题目要求 (16)

2.6.2题目分析与实现方案 (17)

2.6.3关键点与难点 (19)

2.6.4实现代码 (19)

三、测试结果............................................................................................ 2错误!未定义书签。

一、N achos综述

Nachos是一款教学用的操作系统平台,他的全名叫做

“Not Another Completely Heuristic Operating System”,Nachos的

运行必须借助于宿主机,它通过软件模拟了各种硬件系统,包

括中断系统、存储系统、磁盘文件、网络等。它的运行是可

以跟踪的,因此,我们可以一步一步的观察操作系统是如何

运行的。

Nachos操作系统本身只提供了一套框架,很多地方的实现都需要我们自己来完善,因此我们可以通过修改其源代码,来丰富和增强Nachos操作系统的功能.更可以在完善这些功能的同时,了解操作系统的内部运行机制。

二、实验要求:建立线程系统

2.1 Task 1.1:实现KThread.join()

2.11题目要求

实现Implement Kthread.join()函数。其它的线程不必调用join函数,但是如果join()函数被调用的话,也只能被调用一次。对join()函数第二次调用的执行结果是不被定义的,即使第二次调用的线程与第一次调用的线程不同。无论有没有被join,一个进程都能够正常结束。

2.1.2题目分析与实现方案

分析:join函数的作用即为等待调用此函数线程运行完毕。当前线程A调用另一个线程(处于就绪状态) B的join函数时,即A执行B.join()时(A和B在Nachos中均为Kthread类型对象), A被挂起, 直到B运行结束后, join函数返回, A才能继续运行。如果这个线程已经结束,马上返回。且join()函数只能被调用一次,第二次调用不能保证返回,且调用join()函数的线程必须不能是当前线程。Join()函数结束时唤醒在等待队列中的所有线程,因此需要实现join()方法和修改finish()方法。

方案:

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

(2)在线程结束时,finish()函数循环唤醒所有被阻塞的线程。Finish()函数在run()函数返回时自动调用,同样可以被直接调用。但当前唯一运行的线程不能被finish()函数立即结束,只有当其他线程运行时才可结束。

2.1.3关键点与难点

由于java派生于抽象类的对象无法实例化,在运行时很可能出现空指针异常。只能直接利用抽象类的对象调用相关方法。

2.1.4实现代码

public void join() {

Lib.debug(dbgThread, “Joining to thread: “ + toString());

// 判断要调用的进程是否为当前进程(线程只能调用一次join()方法)

Lib.assertTrue(this != currentThread);

// 系统关中断,当前线程休眠

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

if (status != statusFinished) {

// 调用另一个要调用的进程,将当前运行的线程加入到一个阻塞队列中。

waitForJoin.waitForAccess(currentThread);

// 当前进程睡眠等待被调用进程结束

sleep();

}

Machine.interrupt().restore(intStatus);

}

public static void finish() {

Lib.debug(dbgThread, “Finishing thread: “ +

currentThread.toString());

// 系统关中断

Machine.interrupt().disable();// 当前进程运行结束的标志

Machine.autoGrader().finishingCurrentThread();

Lib.assertTrue(toBeDestroyed == null);

// 表示当前进程要结束了

toBeDestroyed = currentThread;

// 当前进程的状态被修改为运行结束

currentThread.status = statusFinished;

// 调用等待队列上的第一个进程

Kthread waitThread;

while ((waitThread = currentThread.waitForJoin.nextThread()) != null) {// 唤醒等待队列上所有被阻塞的进程

waitThread.ready();

}

sleep();

}

2.2 Task 1.2实现条件变量

2.2.1题目要求

利用中断有效和无效所提供的原子性直接实现条件变量。我们已经提供类似的例子实例实现信号量。你要按此提供类似的条件变量的实现,不能直接利用信号量来实现(你可以使用lock,虽然它间接地调用了信号量)。在你完成时要提供条件变量的两种实现方法。你的第二种条件变量实现要放在nachos.threads.Condition2中。

2.2.2题目分析与实现方案

分析:条件变量使我们可以睡眠等待某种条件出现,是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待”条件变量的条件成立”而挂起;另一个线程使”条件成立”(给出条件成立信号)。为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起。

方案:threads.Lock类提供了锁以保证互斥。在临界代码区的两端执行Lock.acquire() 和Lock.release() 即可保证同时只有一个线程访问临界代码区。条件变量建立在锁之上, 由threads.Condition实现,用来保证同步。每一个条件变量拥有一个锁变量。

(1)sleep()在条件变量的控制下sleep()函数自动释放相关锁并进入睡眠状态,直到令一个线程用wake()唤醒它,需要在函数的开始和结尾处关或允许中断保证原子性。当前线程必须拥有相关锁,阻塞进程在sleep()函数返回之前线程将会自动再次拥有锁。即调用这个方法的线程将自己挂起到等待队列,阻塞自己的同时将自己拥有的锁交出去,之后等待锁的分配。拿到锁的线程再次拥有权限接受检验。(2)wake()唤醒条件变量队列中第一个线程,在试验中利用从线程队列中取出线程用Kthread.ready()实现唤醒,加入就绪队列。(同样要在wake函数利用中断保证原子性)

(3)wakeall()函数的实现依赖于wake()。只需不断地wake挂在条件变量上的线程直到队列为空为止。

2.2.3关键点与难点

题目要求直接实现条件变量,不能直接利用信号量。所以互斥锁必须要有,它是线程们有秩序的接受条件变量检验的保证。等待队列必须要有,不满足条件的线程都要挂在上面。

2.2.4实现代码

public static void sleep() {

Lib.debug(dbgThread, “Sleeping thread: “ +

currentThread.toString());

Lib.assertTrue(Machine.interrupt().disabled());

if (currentThread.status != statusFinished)

// 锁住当前线程

currentThread.status = statusBlocked;

// 运行下一个线程

runNextThread();

}

public void wake() {

Lib.assertTrue(conditionLock.isHeldByCurrentThread());

if (!waitQueue.isEmpty())

((Semaphore) waitQueue.removeFirst()).V();

}

public void wakeAll()

{

Lib.assertTrue(conditionLock.isHeldByCurrentThread());

while (!waitQueue.isEmpty())

wake();

}

2.3 Task 1.3 完成Alarm类

2.3.1题目要求

完成Alarm类,通过waitUntil(long x)方法实现。一个线程通过调用waitUntil(long x)方法将自己挂起,一直到经过x时间再被唤醒。这对现实操作很有用,例如,光标的周期闪烁。线程经过x时间后唤醒,

但不需要立刻运行,而是加入readyqueue中。不建立任何多余的线程实现waitUntil(),只需要修改waitUntil()中断处理程序和计时器。waitUntil()不受限于任何一个线程,任何线程可以调用它实现被挂起。

2.3.2题目分析与实现方案

分析:Alarm类使用硬件定时器提供抢占,并允许线程挂起到某个时间。分配的新闹钟设置机器的定时器中断处理程序实现本闹钟的回调,同时Nachos只在有一个计时器的情况下正常运行。

定时器中断处理程序被称为机器计时器定期(大约每500时钟周期)。当前线程产生后,如果有另一个必须运行的线程,则强制上下文切换。

当前线程睡眠至少x时间周期,在定时器中断处理程序中将其唤醒。当现在时间(current time) >= (WaitUntil called time)+(x)时,线程必须被唤醒(在调度准备集)在第一个定时器中断的产生时。

方案:(1)与Alarm类有关的是machine.Timer类,它在大约每500个时钟滴答使调用回调函数(由Timer.setInterruptHandler函数设置)。因此, Alarm类的构造函数中首先要设置该回调函数Alarm.timerInterrupt()。timerInterrupt()方法在每一次timer产生时间中断时遍历队列,检查队列中的时间状态,当线程到了等待的时间就把线程从队列中取出放入就绪队列。

(2)waitUntil()方法使用了一个队列可以存放线程以及唤醒时间,这个队列以时间为序的有序队列。每次调用时,把当前线程和唤醒时间加入队列,等待唤醒。在调用waitUntil(x) 函数时, 首先得

到关于该线程的信息(线程: 当前线程, 唤醒时间: 当前时间+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 {

Waiter(long wakeTime, Kthread thread) {

this.wakeTime = wakeTime;

this.thread = thread;

}

private long wakeTime; // 唤醒时间

private Kthread thread; // 等待的线程

}

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

}

public void waitUntil(long x) {

// 系统关中断

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

// for now, cheat just to get something working (busy waiting is bad)

// 确定唤醒的时间

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);// 当前线程设定唤醒时间并阻塞,挂起

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类,会将事情复杂化。

每个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实现代码

public class Communicator {

public Communicator() {

lock = new Lock();

speaker = new Condition2(lock);

listener = new Condition2(lock);

}

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 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;

}

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

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

lock.acquire();

if (speakercount != 0) {

speaker.wake();

listener.sleep();

} else {

listenercount++;

listener.sleep();

listenercount--;

}

System.out.println(Kthread.currentThread().getName() + “收到信息“

+ Wordqueue.getFirst());

System.out.println();

lock.release();

Machine.interrupt().restore(intStatus);

return Wordqueue.poll();

}

2.5 Task 1.5实现优先级调度

2.5.1题目要求

通过完成实现PriorityScheduler优先级调度策略。所有的调度程序都是继承自Scheduler类,所以必须实现getPriority(), getEffectivePriority()和setPriority()方法。

2.5.2题目分析与实现方案

分析:Nachos系统已经提供了一个简单的轮转调度器,采用简单的FIFO队列进行调度。优先级调度的传统算法如下: 每个线程拥有一个优先级(在Nachos中, 优先级是一个0到7之间的整数, 默认为1)。在线程调度时, 调度程序选择一个拥有最高优先级的处于就绪状态的线程运行。这种算法的问题是可能出现“饥饿”现象。为解决上述优先级反转问题, 需要实现一种“让出”优先级的机制(Priority Donation) 。getEffectivePriority()就是为了解决优先级翻转而设的,也就是说当出现一个优先级高的线程等待低优先级线程时,若存在另外的高优先级线程而导致低优先级线程永远不能执行的情况,该低优先

级线程调用该函数返回它持有的锁上等待的所有线程中优先级中最高的一个给该优先级线程,以确保它执行。

方案:在引入优先级的同时就需要引入一个ThreadState对象,它用来把线程和优先级绑定在一起。而且内部还有一个队列用来记录等待它的线程。在ThreadState类中增加两个LinkedList<>类表,存放PriorityQueue。一个表用来记录该线程所占用资源的优先队列,另一个表用来记录该线程所想占有的资源的优先队列。占用资源的队列作为发生优先级反转时,捐献优先级计算有效优先级的来源依据,想占有的资源的队列用来为线程声明得到资源做准备。getEffectivePriority():计算有效优先级时,遍历等待队列中所用线程的有效优先级,找出最大的优先级。首先要在PriorityQueue类下创建个装有Kthread的LinkedList,即等待队列waitQueue,声明一个effectivePriority,遍历waitQueue,找出priority最大的那个Kthread,将它的priority赋给effectivePriority,然后返回即可。

而在队列类中最重要的就是nextThread()方法,它返回下一个要执行的线程。这个方法通过遍历队列,计算出所有线程的有效优先级,取出有效优先级最大的线程执行。

waitForAccess()将需要等待获得资源的线程加入一个等待队列等待调度。

2.5.3关键点与难点

解决这个问题的关键是计算有效优先级,在改变优先级的时候计算。优先级在捐献之后不会丢失并可以不断传递下去。在

PriorityScheduler类的内部类。ThreadState类里有priority这属性,所以实现getPriority(), setPriority(), increasePriority(), decreasePriority()时直接对priority进行返回,重新赋值,修改priority的值。(注意:getPriority(), setPriority()函数内部是先调用内部类ThreadState类的同名函数,然后在这些同名函数里对priority修改)。

2.5.4实现代码

protected class ThreadState {

public ThreadState(Kthread thread) {

this.thread = thread;

setPriority(priorityDefault);

}

public int getPriority() {

return priority;

}

public int getEffectivePriority() {

return priority;

}

public void setPriority(int priority) {

if (this.priority == priority)

return;

this.priority = priority;

}

public void waitForAccess(PriorityQueue waitQueue) {

if (waitQueue.holder != null)

if (this.priority > waitQueue.holder.priority) {

waitQueue.holder.priority = this.priority;

}

waitQueue.waitQueue.add(this);

}

public void acquire(PriorityQueue waitQueue) {

// implement me

Lib.assertTrue(Machine.interrupt().disabled());

Lib.assertTrue(waitQueue.waitQueue.isEmpty());

waitQueue.holder = this;

}

protected Kthread thread;

protected int priority;

}

public Kthread nextThread() {

Lib.assertTrue(Machine.interrupt().disabled());

// implement me

if (waitQueue.isEmpty())

return null;

int max_priority = 0;

int index = 0;

int m = 0;

for (Iterator I = waitQueue.iterator(); i.hasNext();) { ThreadState o = (ThreadState) i.next();

if (o.priority > max_priority) {

index = m;

max_priority = o.priority;

}

m++;

}

ThreadState nextState = waitQueue.remove(index);

if (holder != null) {

holder = nextState;

}

return nextState.thread;

}

2.6 Task 1.6 条件变量解决过河问题

2.6.1题目要求

利用前面所学同步方法,以及条件变量解决过河问题。一群夏威夷人想要从瓦胡岛(Oahu)到摩洛凯岛(Molokai),只有一艘船,该船可载最多2个小孩或一个成人,且必须有一个开船的人(默认每个人都会开船)。设计一个解决方案,使得每个人都能从Oahu到Molokai。假设至少有两个小孩,每一个人都会划船。要为每个大人

和孩子创建一个线程,这个线程就相当于一个人,他们能自己判断(思考),什么时候可以过河,而不是通过调度程序的调度。在解决问题的过程中不能出现忙等待,而且问题最终一定要解决。不符合逻辑的事情不能发生,比如在这个岛的人能知道对面岛的情况。

2.6.2题目分析与实现方案

需要记录的信息有:

1.O岛上大人/小孩的人数和M岛上大人/小孩的人数

1)船的位置(在O岛还是M岛) 和状态(空/半满/全满) (半满指只有一个小孩, 全满指有两个小孩或一个大人)

2.是否最后一次运输

3.孩子、大人信息的条件变量,并且需要一个锁

运送过程大体如下:

1:所以我们可以尽可能多的先从O岛把孩子运过来(M岛到O 岛需要一个child驾驶员,要避免出现当大人到M岛上而没有孩子在M岛上出现这种情况)

2:然后开始运输大人,并且让孩子把船开回O岛

3:重复1,2

4:最后将两个孩子运到M岛

对于大人,若满足以下条件则独自乘船过河(每个大人过且仅过一次河, 线程即告结束), 否则(在O岛)等待:

2)O岛上只有一个小孩或没有小孩

3)2)船在O岛

4)3)船为空

对于小孩, 满足以下情况则乘船过河:

1)初始条件,小孩全在O岛, 船在O岛,且M岛没有小孩。

2)某小孩在O岛, 船在O岛, 船为空, O岛上的小孩数大于等于2,则该小孩上船等另外一个小孩上船后,两人一起划船过河到M。

3)某小孩在O岛, 船在O岛, 船为空, O岛上没有大人: 该小孩上船过河

4)当所有的大人运完了之后,O岛出现了两个孩子,这个时候这两个孩子划船过河。

方案:使用一个锁变量保证互斥,四个条件变量保证同步。结构如下:程序首先创建大人线程和孩子线程——获取锁——唤醒一个孩子进程——释放锁。

ChildItinerary()思路:

先获得锁conditionLock.acquire()并处于等待状态childOnOahu.sleep();

判断是否为最后一次运输若是最后一次,直接进行运输并结束。若不是,则判断是否在Oahu。若在,O岛孩子数减一。判断是否有驾驶员,若有,直接进行运输ChildRideToMolokai();若没有驾驶员,他将成为驾驶员并唤醒一个孩子线程。

若孩子在M岛,则将船开回O岛,O岛孩子数量改变。如果O 岛孩子数为1则唤醒大人线程,准备运送大人,否则唤醒孩子线程,继续运送孩子。

AdultItinerary()思路:与ChildItinerary思想类似,但少了返回O 岛这一步。大体为获得锁conditionLock.acquire()并进入等待状态adultOnOahu.sleep(),直接去M岛然后唤醒M岛一个孩子。

2.6.3关键点与难点

难点在渡河过程分析。只有小孩可以有返程路线,大人返程没有意义;要避免出现当大人到M岛上而没有孩子在M岛上出现这种情况。开始之前让所有人sleep, 然后begin()叫醒一个child, 然后每次一个人干完了活叫醒另一个然后自己睡,所有人都是被动的,相比所有人都主动竞争当驾驶员或乘客,这样可以避免冲突。

2.6.4实现代码

public class Boat {

public static void selfTest(int i, int j) {

BoatGrader b = new BoatGrader();

childrenOnOahuBG = j;

childrenOnMolokaiBG = 0;

adultOnOahuBG = i;

adultOnMolokaiBG = 0;

System.out.println(j + " children and " + i + " adults.");

begin(i, j, b);

}

public static void begin(int adults, int children, BoatGrader b) { bg = b;

lock1 = new Lock();

childrenWaitOnOahu = new Condition(lock1);

lock2 = new Lock();

adultWaitOnOahu = new Condition(lock2);

lock3 = new Lock();

childrenReadyOnMolokai = new Condition(lock3);

for (int i = 0; i < adults; i++) {

new KThread(new Adult(childrenWaitOnOahu, adultWaitOnOahu,

childrenReadyOnMolokai)).setName("adult").fork();

}

for (int i = 0; i < children - 1; i++) {

new KThread(new Child(childrenWaitOnOahu, adultWaitOnOahu,

childrenReadyOnMolokai)).setName("child").fork();

}

KThread t = new KThread(new Child(childrenWaitOnOahu, adultWaitOnOahu,

childrenReadyOnMolokai));

t.setName("child");

t.fork();

KThread.currentThread().yield();

lock1.acquire();

childrenWaitOnOahu.wake();

lock1.release();

t.join();

}

static void AdultItinerary() {

bg.initializeAdult();

adultOnOahu++;

lock2.acquire();

adultWaitOnOahu.sleep();

bg.AdultRowToMolokai();

adultOnOahu--;

adultOnMolokai++;

lock2.release();

lock3.acquire();

childrenReadyOnMolokai.wake();

lock3.release();

}

static void ChildItinerary() {

// 创建一个划船的孩子

bg.initializeChild();

childrenOnOahu++;

lock1.acquire();

childrenWaitOnOahu.sleep();

lock1.release();

while (true) {

if (pilot != 1) {

if (childrenOnOahu > 1) // 有孩子

{

lock1.acquire();

childrenWaitOnOahu.wake();

pilot = 1;// 运孩子

bg.ChildRowToMolokai();

childrenOnOahu--;

操作系统课程设计

课程设计报告 2015~2016学年第一学期 操作系统综合实践课程设计 实习类别课程设计 学生姓名李旋 专业软件工程 学号130521105 指导教师崔广才、祝勇 学院计算机科学技术学院 二〇一六年一月

- 1 -

- 2 -

一、概述 一个目录文件是由目录项组成的。每个目录项包含16B,一个辅存磁盘块(512B)包含32个目录项。在目录项中,第1、2字节为相应文件的外存i节点号,是该文件的内部标识;后14B为文件名,是该文件的外部标识。所以,文件目录项记录了文件内、外部标识的对照关系。根据文件名可以找到辅存i节点号,由此便得到该文件的所有者、存取权、文件数据的地址健在等信息。UNIX 的存储介质以512B为单位划分为块,从0开始直到最大容量并顺序加以编号就成了一个文件卷,也叫文件系统。UNIX中的文件系统磁盘存储区分配图如下: 本次课程设计是要实现一个简单的模拟Linux文件系统。我们在内存中开辟一个虚拟磁盘空间(20MB)作为文件存储器,并将该虚拟文件系统保存到磁盘上(以一个文件的形式),以便下次可以再将它恢复到内存的虚拟磁盘空间中。文件存储空间的管理可采用位示图方法。 二、设计的基本概念和原理 2.1 设计任务 多用户、多级目录结构文件系统的设计与实现。可以实现下列几条命令login 用户登录 logout 退出当前用户 dir 列文件目录 creat 创建文件 delete 删除文件 open 打开文件 close 关闭文件 - 3 -

read 读文件 write 写文件 mkdir 创建目录 ch 改变文件目录 rd 删除目录树 format 格式化文件系统 Exit 退出文件系统 2.2设计要求 1) 多用户:usr1,usr2,usr3,……,usr8 (1-8个用户) 2) 多级目录:可有多级子目录; 3) 具有login (用户登录)4) 系统初始化(建文件卷、提供登录模块) 5) 文件的创建:create (用命令行来实现)6) 文件的打开:open 7) 文件的读:read8) 文件的写:write 9) 文件关闭:close10) 删除文件:delete 11) 创建目录(建立子目录):mkdir12) 改变当前目录:cd 13) 列出文件目录:dir14) 退出:logout 新增加的功能: 15) 删除目录树:rd 16) 格式化文件系统:format 2.3算法的总体思想 - 4 -

操作系统课程设计题目

课程设计任务书 一、课程设计目的 《计算机操作系统》课程设计是计算机类专业的集中实践性环节之一,是学习完《计算机操作系统》课程后进行的一次全面的综合练习。其目的在于加深对操作系统课程的理解,使学生更好地掌握操作系统的基本概念、基本原理、及基本功能,理解操作系统在计算机系统中的作用、地位和特点,具有分析实际操作系统,设计、构造和开发现代操作系统的基本能力,为今后从事的各种实际工作,如设计、分析和改进各种系统软件和应用软件提供必要的软件理论基础。 二、课程设计内容及要求 课程设计要求: 每位同学从下述设计任务中任选一个任务完成,上机验收运行结果,现场提问,并提交所完成该任务的课程设计报告。 实验要求: 1)上机前认真使用C语言编写好程序,采用Visual C++6.0作为编译环境; 2)上机时独立调试程序 3)上机验收运行结果,现场提问 4)根据具体任务要求,提交课程设计实验报告,报告内容包括:课程设计目的、内容、基本原理、模块划分、数据结构、算法设计、程序流程图(包括主程序流程图、模块详细设计流程图等)、以及算法源码(必须有相关注释,以有助于说明问题为宜,不得全盘打印而不加任何注释)、心得体会等。

设计内容一页式虚拟存储管理页面置换算法 1.目的和要求 在熟练掌握计算机虚拟存储技术的原理的基础上,利用一种程序设计语言模拟实现几种置换算法,一方面加深对原理的理解,另一方面提高学生通过编程根据已有原理解决实际问题的能力,为学生将来进行系统软件开发和针对实际问题提出高效的软件解决方案打下基础 2.实验内容 阅读教材《计算机操作系统》,掌握存储器管理相关概念和原理。 模拟实现页式虚拟存储管理的三种页面置换算法(OPT、FIFO和LRU),并通过比较性能得出结论。 前提: (1)页面分配采用固定分配局部置换。 (2)作业的页面走向和分得的物理块数预先指定。可以从键盘输入也可以从文件读入。 (3)置换算法的置换过程输出可以在显示器上也可以存放在文件中,但必须清晰可读,便于检验。 3.实验环境 Windows操作系统、VC++6.0、C语言 4.实验提示 (1)基础知识 存储管理是操作系统进行资源管理的一个重要功能。现代操作系统广泛采用虚

操作系统课程设计报告书

题目1 连续动态内存管理模拟实现 1.1 题目的主要研究内容及预期达到的目标 (1)针对操作系统中内存管理相关理论进行设计,编写程序并进行测试,该程序管理一块虚拟内存。重点分析三种连续动态内存分配算法,即首次适应算法、循环首次适应算法和最佳适应算法。 (2)实现内存分配和回收功能。 1.2 题目研究的工作基础或实验条件 (1)硬件环境:PC机 (2)软件环境:Windows XP,Visual C++ 6.0 1.3 设计思想 首次适应算法的实现:从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,这种方法的目的在于减少查找时间。为适应这种算法,空闲分区表中的空闲分区要按地址由低到高进行排序。该算法优先使用低址部分空闲区,在低址空间造成许多小的空闲区,在高址空间保留大的空闲区。 循环首次适应算法的实现:在分配内存空间时,不再每次从表头开始查找,而是从上次找到空闲区的下一个空闲开始查找,直到找到第一个能满足要求的的空闲区为止,并从中划出一块与请求大小相等的内存空间分配给作业。该算法能使内存中的空闲区分布得较均匀。 最佳适应算法的实现:从全部空闲区中找到能满足作业要求的、且最小的空闲分区,这种方法能使碎片尽量小。为适应此算法,空闲分区表中的空闲分区要按从小到大进行排序,从表头开始查找第一个满足要求的自由分配。 1.4 流程图 内存分配流程图,如图1-1所示。

图1-1 内存分配流程图内存回收流程图,如1-2所示。

图1-2 内存回收流程图 1.5 主要程序代码 (1)分配内存 void allocate(char z,float l) { int i,k; float ad; k=-1; for(i=0;i= l && free_table[i].flag == 1) if(k==-1 || free_table[i].length

单片机电子时钟课程设计实验报告

单片机电子时钟课程设 计实验报告 Pleasure Group Office【T985AB-B866SYT-B182C-BS682T-STT18】

《单片机原理与应用》课程设计 总结报告 题目:单片机电子时钟(带秒表)的设计 设计人员:张保江江润洲 学号: 班级:自动化1211 指导老师:阮海容 目录 1.题目与主要功能要求 (2) 2.整体设计框图及整机概述 (3) 3.各硬件单元电路的设计、参数分析及原理说明 (3) 4.软件流程图和流程说明 (4) 5.总结设计及调试的体会 (10) 附录 1.图一:系统电路原理图 (11) 2.图二:系统电路 PCB (12) 3.表一:元器件清单 (13) 4.时钟程序源码 (14)

题目:单片机电子时钟的设计与实现 课程设计的目的和意义 课程设计的目的与意义在于让我们将理论与实践相结合。培养我们综合运用电子课程中的理论知识解决实际性问题的能力。让我们对电子电路、电子元器件、印制电路板等方面的知识进一步加深认识,同时在软件编程、排错调试、焊接技术、相关仪器设备的使用技能等方面得到较全面的锻炼和提高,为今后能够独立完成某些单片机应用系统的开发和设计打下一个坚实的基础。 课程设计的基本任务 利用89C51单片机最小系统,综合应用单片机定时器、中断、数码显示、键盘输入等知识,设计一款单片机和简单外设控制的电子时钟。 主要功能要求 最基本要求 1)使用MCS-51单片机设计一个时钟。要求具有6位LED显示、3个按键输入。 2)完成硬件实物制作或使用Pruteus仿真(注意位驱动应能提供足够的电流)。 3)6位LED数码管从左到右分别显示时、分、秒(各占用2位),采用24小时标准计时制。开始计时时为000000,到235959后又变成000000。 4)使用3个键分别作为小时、分、秒的调校键。每按一次键,对应的显示值便加1。分、秒加到59后再按键即变为00;小时加到23后再按键即变为00。在调校时均不向上一单位进位 (例如分加到59后变为00,但小时不发生改变)。 5) 软件设计必须使用MCS-51片内定时器,采用定时中断结构,不得使用软件延时法,也不得使用其他时钟芯片。 6)设计八段数码管显示电路并编写驱动程序,输入并调试拆字程序和数码显示程序。7)掌握硬件和软件联合调试的方法。 8)完成系统硬件电路的设计和制作。 9)完成系统程序的设计。 10)完成整个系统的设计、调试和制作。

《操作系统课程设计》题目要求

操作系统课程设计要求 一.设计目的 熟悉Linux编程环境,加强对Linux命令的理解及函数的运用 二.设计内容 1. 在Linux环境下模拟实现简单命令解释器。 (1)要求实现的基本命令包括: pwd //显示当前所在目录的路径名 dir <目录名> //列出指定目录名中的所有目录及文件 cd <目录名或路径>//改变当前工作目录 newdir <目录名> //新建目录 deldir <目录名> //删除目录 exit //退出命令解释程序 (2)可选做的扩展命令包括: rename <旧文件名> <新文件名> //重命名一个文件或目录 find <目录> -name <待查找的文件名> //在指定的目录及其子目录中查找指定的文件date //显示当前日期 (3)提示:整个程序的大致框架可参考如下: while ( exit未被输入) { 接收键盘的一行输入 分析输入的命令 对输入的命令进行处理,调用系统函数实现功能 } 2. 设计要求 (1) 设计必须在Linux环境下进行。 (2) 命令解释程序的提示符为:姓名拼音@ (3) 程序编写中不得使用system()系统调用。 (4) 整个程序必须严格经过测试,完成所有基本功能。源程序应有较详尽的注释。 3.可能用到的系统调用: open(),close(),read(),write(),creat() chdir(), opendir(),readdir(),rewinddir(),closedir(),rmdir(),mkdir() getcwd(), ftw() time(), localtime(), asctime()

操作系统课程设计报告

操作系统课程设计报告

东莞理工学院 操作系统课程设计报告 学院:计算机学院 专业班级: 13软件工程1班 提交时间: 2015/9/14 指导教师评阅意见: . 项目名称:进程与线程管理功能 一、设计目的 用语言来模拟进程和线程管理系统,加深对进程和线程的理解,掌握对进程和线程各种状态和管理的算法原理。

二、环境条件 系统: WindowsXP、VMWare、Ubuntu Linux 语言:C/C++ 开发工具:gcc/g++、Visual C++ 6.0 三、设计内容 1. 项目背景 计算机的硬件资源有限,为了提高内存的利用率和系统的吞吐量,就要根据某种算法来管理进程和线程的状态从而达到目的。 进程与线程管理功能完成基于优先级的抢占式线程调度功能,完成进程虚拟内存管理功能。 进程与线程管理功能 基本要求:完成基于优先级的抢占式线程调度功能,完成进程虚拟内存管理功能。 提高要求:(增加1项就予以加分) (1) 实现多种线程调度算法; (2)通过“公共信箱”进行通信的机制,规定每一封信的大小为128字节,实现两个用户进程之间通过这个“公共信箱”进行通信。 (3) 实现多用户进程并发的虚拟内存管理功能。

(4) 实现用户进程间通信功能,并用生产者/消费者问题测试进程间通信功能的正确性。 (5) 实现改进型Clock页面置换算法。 (6) 实现Cache功能,采用FIFO替换算法。 2. 扩展内容 实现多种线程调度算法:时间片轮转调度算法 四、人员分工 优先级调度算法:钟德新,莫友芝 时间片轮转调度算法:张德华,袁马龙 设计报告由小组队员共同完成。小组成员设计的代码分工如下:钟德新编写的代码:void Prinft(){ PCB *p; system("cls");//清屏 p=run; //运行队列 if(p!=NULL) { p->next=NULL; } cout<<"当前正在运行的进程:"<procname<<"\t\t"<pri<<"\t"<needOftime<<"\t\t"<runtime<<"\t\t"<state<next; } cout<

vf课程设计实验报告模板

vf 课程设计实验报告模板 经济管理学院 学生信息管理系统的设计与实现 09年12 月28 日 、课程设计的目的和意义 当今,人类正在步入一个以智力资源的占有和配置,知识生产、分配和使用为最重要因素的知识经济时代,为了适应知识经济时代发展的需要,大力推动信息产业的发展,我们通过对学生信息管理系统的设计,来提高学生的操作能力,及对理论知识的实践能力,从而提高学生的基本素质,使其能更好的满足社会需求。 学生信息管理系统是一个简单实用的系统,它是学校进行学生管理的好帮手。 此软件功能齐全,设计合理,使用方便,适合各种学校对繁杂的学生信息进行统筹管理,具有严格的系统使用权限管理,具有完善的管理功能,强大的查询功能。它可以融入学校的信息管理系统中,不仅方便了学生信息各方面的管理,同时也为教师的管理带来了极大地便利。 我们进行本次课程设计的主要目的是通过上机实践操作,熟练掌握数据库的设 计、表单的设计、表单与数据库的连接、SQL语言的使用和了解它的功能:数据定 义、数据操纵、数据控制,以及简单VF程序的编写。基本实现学生信息的管理, 包括系统的登录、学生信息的录入、学生信息的浏览、学生信息的查询、学生信息的修改和学生信息的删除,并对Visual FoxPro6.0 的各种功能有进一步的了解,为我们更进一步深入的学习奠定基础,并在实践中提高我们的实际应用能力,为我们以后的学习和工作提供方便,使我们更容易融入当今社会,顺应知识经济发展的趋势。 - 1 -

、系统功能设计 通过该系统可以基本实现学生信息的管理,包括系统的登录、学生信息的录 入、学生信息的浏览、学生信息的查询、学生信息的修改和学生信息的删除。系统 功能模块如下图所示。 学生信息管理系统主界面 登录 管理 学学学学学 生生生生生 信信信信信 息息息息息 录查浏修删 入询览改除 三、系统设计内容及步骤 3.1创建项目管理文件 1.启动foxpro 系统,建一个项目管理器,命名为“学生管理”。 哑 目f ■ 也 电 岂同左 矣 氏H. 0 存 JI 蛋誤曾

操作系统课程设计报告

上海电力学院 计算机操作系统原理 课程设计报告 题目名称:编写程序模拟虚拟存储器管理 姓名:杜志豪.学号: 班级: 2012053班 . 同组姓名:孙嘉轶 课程设计时间:—— 评语: 成绩: 目录 一、设计内容及要求 (4) 1. 1 设计题目 (4) 1.2 使用算法分析: (4)

1. FIFO算法(先进先出淘汰算法) (4) 1. LRU算法(最久未使用淘汰算法) (5) 1. OPT算法(最佳淘汰算法) (5) 分工情况 (5) 二、详细设计 (6) 原理概述 (6) 主要数据结构(主要代码) (6) 算法流程图 (9) 主流程图 (9) Optimal算法流程图 (10) FIFO算法流程图 (10) LRU算法流程图 (11) .1源程序文件名 (11) . 2执行文件名 (11) 三、实验结果与分析 (11) Optimal页面置换算法结果与分析 (11) FIFO页面置换算法结果与分析 (16) LRU页面置换算法结果与分析 (20) 四、设计创新点 (24) 五、设计与总结 (27)

六、代码附录 (27) 课程设计题目 一、设计内容及要求 编写程序模拟虚拟存储器管理。假设以M页的进程分配了N

块内存(N

操作系统-课程设计

课程设计说明书(操作系统) 题目:进程调度 院系:计算机科学与工程学院 专业班级:信息安全13-2 学号:20133029xx 学生姓名:xx 指导教师:xx 2015年12月15日

安徽理工大学课程设计(论文)任务书计算机科学与工程学院

安徽理工大学课程设计(论文)成绩评定表

摘要 现代计算机系统中,进程是资源分配和独立运行的基本单位,是操作系统的核心概念。因而,进程就成为理解操作系统如何实现系统管理的最基本,也是最重要的概念。进程调度是进程管理过程的主要组成部分,是必然要发生的事件。 在现代操作系统中,进程的并发机制在绝大多数时候,会产生不断变化的进程就绪队列和阻塞队列。处于执行态的进程无论是正常或非正常终止、或转换为阻塞状态,都会引发从就绪队列中,由进程调度选择一个进程进占CPU。 进程调度的核心是进程调度的算法.在本课程设计中,用良好清晰的界面向用户展示了进程调度中的时间片轮转调度算法。在最终实现的成果中,用户可指定需要模拟的进程数,CPU时间片和进程的最大执行时间,并且选择需要演示的算法,界面将会动态的显示进程调度过程及各个队列的变化。通过此进程调度模拟系统,用户可以对时间片轮转调度算法有进一步以及直观的了解。 关键词:进程,调度,PCB,时间片轮转

目录 1.设计目的 (6) 2.设计思路 (6) 3.设计过程 (8) 3.1流程图 (8) 3.2算法 (8) 3.3数据结构 (10) 3.4源代码 (10) 4.实验结果及分析 (20) 4.1 使用说明 (20) 4.2程序演示 (20) 5.实验总结 (24) 6.参考文献 (24)

2017操作系统(含课程设计) - 随堂练习

随堂练习提交截止时间:2017-12-15 23:59:59 当前页有10题,你已做10题,已提交10题,其中答对10题。 1.(单选题) 操作系统是基本的特征是() A、并发 B、共享 C、虚拟 D、异步 答题: A. B. C. D. (已提交) 参考答案:A 问题解析: 2.(单选题) 下面不属于操作系统设计目标的是() A、提高资源利用率 B、提高系统吞吐量 C、用户操作计算机更方便 D、并行执行多个进程 答题: A. B. C. D. (已提交) 参考答案:D 问题解析: 3.(单选题) 历史上最早出现的操作系统是() A、单道批处理系统 B、多道批处理系统 C、分时系统 D、实时系统 答题: A. B. C. D. (已提交) 参考答案:A 问题解析: 4.(单选题) 实时操作系统必须在()内处理完来自外部的事件。 A、响应时间 B、周转时间 C、被控对象规定时间 D、调度时间 答题: A. B. C. D. (已提交) 参考答案:C 问题解析: 5.(单选题) 操作系统是对()进行管理的软件。 A、软件 B、硬件 C、计算机资源 D、应用程序 答题: A. B. C. D. (已提交) 参考答案:C 问题解析: 6.(单选题) 配置了操作系统的计算机是一台比原来的物理计算机功能更强的计算机,这样的一台计算机只是一台逻辑上的计算机,称为()计算机。 A、并行 B、真实 C、虚拟 D、共享 答题: A. B. C. D. (已提交)

问题解析: 7.(单选题) 操作系统中采用多道程序设计技术提高了CPU和外部设备的() A、利用率 B、可靠性 C、稳定性 D、兼容性 答题: A. B. C. D. (已提交) 参考答案:A 问题解析: 8.(单选题) 在操作系统中,并发性是指若干事件____发生( ) A、在同一时刻 B、在不同时刻 C、在某一时间间隔内 D、依次在不同时间间隔内 答题: A. B. C. D. (已提交) 参考答案:C 问题解析: 9.(单选题) ()操作系统允许在一台主机上同时联接多台终端,多个用户可以通过各自的终端同时交互地使用计算机。 A、网络操作系统 B、批处理操作系统 C、实时操作系统 D、分时操作系统 答题: A. B. C. D. (已提交) 参考答案:D 问题解析: 10.(单选题) 下面关于操作系统的叙述中正确的是 ( ) A、批处理作业必须提交作业控制信息 B、分时系统不一定都具有人机交互功能 C、从响应时间的角度看,实时系统与分时系统差不多 D、由于采用了分时技术,用户可以独占计算机的资源 答题: A. B. C. D. (已提交) 参考答案:A 问题解析:

操作系统课程设计报告

东莞理工学院 操作系统课程设计报告学院:计算机学院 专业班级:13软件工程1班 提交时间:2015/9/14 指导教师评阅意见: . 项目名称:进程与线程管理功能 一、设计目的 用语言来模拟进程和线程管理系统,加深对进程和线程的理解,掌握对进程和线程各种状态和管理的算法原理。 二、环境条件 系统:WindowsXP、VMWare、Ubuntu Linux 语言:C/C++ 开发工具:gcc/g++、Visual C++ 6.0 三、设计内容 1. 项目背景

计算机的硬件资源有限,为了提高内存的利用率和系统的吞吐量,就要根据某种算法来管理进程和线程的状态从而达到目的。 进程与线程管理功能完成基于优先级的抢占式线程调度功能,完成进程虚拟内存管理功能。 进程与线程管理功能 基本要求:完成基于优先级的抢占式线程调度功能,完成进程虚拟内存管理功能。 提高要求:(增加1项就予以加分) (1) 实现多种线程调度算法; (2)通过“公共信箱”进行通信的机制,规定每一封信的大小为128字节,实现两个用户进程之间通过这个“公共信箱”进行通信。 (3) 实现多用户进程并发的虚拟内存管理功能。 (4) 实现用户进程间通信功能,并用生产者/消费者问题测试进程间通信功能的正确性。 (5) 实现改进型Clock页面置换算法。 (6) 实现Cache功能,采用FIFO替换算法。 2. 扩展内容 实现多种线程调度算法:时间片轮转调度算法 四、人员分工 优先级调度算法:钟德新,莫友芝 时间片轮转调度算法:张德华,袁马龙 设计报告由小组队员共同完成。小组成员设计的代码分工如下: 钟德新编写的代码:void Prinft(){ PCB *p; system("cls");//清屏 p=run; //运行队列 if(p!=NULL) { p->next=NULL; } cout<<"当前正在运行的进程:"<procname<<"\t\t"<pri<<"\t"<needOftime<<"\t\t"<runtime<<"\t\t"<state<next; } cout<procname<<"\t\t"<pri<<"\t"<needOftime<<"\t\t"<runtime<<"\t\t"<state<next; } cout<

【实验报告】大学物理实验课程设计实验报告

大学物理实验课程设计实验报告北方民族大学 大学物理实验(设计性实验) 实验报告 指导老师:王建明 姓名:张国生 学号:XX0233 学院:信息与计算科学学院 班级:05信计2班 重力加速度的测定 一、实验任务 精确测定银川地区的重力加速度 二、实验要求 测量结果的相对不确定度不超过5% 三、物理模型的建立及比较 初步确定有以下六种模型方案: 方法一、用打点计时器测量

所用仪器为:打点计时器、直尺、带钱夹的铁架台、纸带、夹子、重物、学生电源等. 利用自由落体原理使重物做自由落体运动.选择理想纸带,找出起始点0,数出时间为t的p点,用米尺测出op的距离为h,其中t=0.02秒×两点间隔数.由公式h=gt2/2得g=2h/t2,将所测代入即可求得g. 方法二、用滴水法测重力加速度 调节水龙头阀门,使水滴按相等时间滴下,用秒表测出n个(n取 50―100)水滴所用时间t,则每两水滴相隔时间为t′=t/n,用米尺测出水滴下落距离h,由公式h=gt′2/2可得g=2hn2/t2. 方法三、取半径为r的玻璃杯,内装适当的液体,固定在旋转台上.旋转台绕其对称轴以角速度ω匀速旋转,这时液体相对于玻璃杯的形状为旋转抛物面重力加速度的计算公式推导如下: 取液面上任一液元a,它距转轴为x,质量为m,受重力mg、弹力n.由动力学知: ncosα-mg=0(1) nsinα=mω2x(2) 两式相比得tgα=ω2x/g,又tgα=dy/dx,∴dy=ω2xdx/g, ∴y/x=ω2x/2g.∴g=ω2x2/2y. .将某点对于对称轴和垂直于对称轴最低点的直角坐标系的坐标x、y测出,将转台转速ω代入即可求得g.

操作系统课程设计论文

学年论文(课程设计)题目:操作系统课程设计 学院数学与计算机学院 学科门类工学 专业网络工程 学号 姓名 指导教师王煜 年月日

河北大学学年论文(课程设计)任务书 (指导教师用表) 指导教师签字: 系主任签字: 主管教学院长签字: 装 订 线

河北大学学年论文(课程设计)成绩评定表学院:数学与计算机学院 装 订 线

摘要 此系统实现了存储管理、设备管理和进程管理。 存储管理部分主要实现主存空间的分配和回收。存储管理采用可移动的可变分区存储管理方式。采用数组来模拟主存,大小为512个字节。 设备管理主要包括设备的分配和回收。模拟系统中有A、B、C三种独占型设备,A设备3个,B设备2个,C设备1个。设备分配时采用采用先来先服务策略。设备回收时唤醒等待设备的进程。 进程管理主要包括进程调度,进程的创建和撤销、进程的阻塞和唤醒,中断作用的实现。其中硬件中的中央处理器用不断循环的函数CPU( )模拟,重要寄存器(如:程序状态寄存器PSW、指令寄存器IR)用全局变量模拟,中断的发现是在函数CPU中加检测PSW 的方式来模拟,时钟的模拟通过timer控件实现。进程控制块的模拟通过数组,本系统最多容纳10个。进程调度时采用时间片轮转调度算法,时间片为5。 关键词:存储管理设备管理进程管理时间片

ABSTRACT The system has storage management, equipment management and process management. The storage management has achieved the allocation and recovery of the main memory space. Variable storage management is used as storage management .We simulate the main memory by array, whose size is 512 bytes. The device management, including the distribution and recovery of devicet. We simulate three devices ,A,B,C. the numbers of them are 3,2,1. The distribution of device used to adopt first-come first-service strategy. It awakes the blocking process when the device is recycled. The process management, including scheduling ,creating revocation ,blocking and waking up the process, the realization of the interruption.We simulate the central processing unit by the cycling function named CPU(),simulate the important register by global variable, simulate the recovering of interruption by checking PSW in the function of CPU(),simulate the clock by the timer control. The simulation of the process control block by array, whose number is up to 10. When the scheduling of the process happens, we use the algorithm of time piece rotation scheduling, and the time piece is 5. Key words: storage device process time

操作系统课程设计报告

东莞理工学院 操作系统课程设计报告 学院:计算机学院 专业班级:13软件工程1班 提交时间:2015/9/14 指导教师评阅意见: . 项目名称:进程与线程管理功能 一、设计目的 用语言来模拟进程和线程管理系统,加深对进程和线程的理解,掌握对进程和线程各种状态和管理的算法原理。 二、环境条件

系统:WindowsXP、VMWare、Ubuntu Linux 语言:C/C++ 开发工具:gcc/g++、Visual C++ 6.0 三、设计内容 1. 项目背景 计算机的硬件资源有限,为了提高内存的利用率和系统的吞吐量,就要根据某种算法来管理进程和线程的状态从而达到目的。 进程与线程管理功能完成基于优先级的抢占式线程调度功能,完成进程虚拟内存管理功能。 进程与线程管理功能 基本要求:完成基于优先级的抢占式线程调度功能,完成进程虚拟内存管理功能。 提高要求:(增加1项就予以加分) (1) 实现多种线程调度算法; (2)通过“公共信箱”进行通信的机制,规定每一封信的大小为128字节,实现两个用户进程之间通过这个“公共信箱”进行通信。 (3) 实现多用户进程并发的虚拟内存管理功能。 (4) 实现用户进程间通信功能,并用生产者/消费者问题测试进程间通信功能的正确性。 (5) 实现改进型Clock页面置换算法。 (6) 实现Cache功能,采用FIFO替换算法。

2. 扩展内容 实现多种线程调度算法:时间片轮转调度算法 四、人员分工 优先级调度算法:钟德新,莫友芝 时间片轮转调度算法:张德华,袁马龙 设计报告由小组队员共同完成。小组成员设计的代码分工如下:钟德新编写的代码:void Prinft(){ PCB *p; system("cls");//清屏 p=run; //运行队列 if(p!=NULL) { p->next=NULL; } cout<<"当前正在运行的进程:"<procname<<"\t\t"<pri<<"\t"<needOftime<<"\t\t"<runtime<<"\t\t"<state<next; } cout<procname<<"\t\t"<pri<<"\t"<needOftime<<"\t\t"<runtime<<"\t\t"<state<next; } cout<procname<<"\t\t"<pri<<"\t"<needOftime<<"\t\t"<runtime<<"\t\t"<state<

南邮课程设计实验报告

课程设计I报告 题目:课程设计 班级:44 姓名:范海霞 指导教师:黄双颖 职称: 成绩: 通达学院 2015 年 1 月 4 日

一:SPSS的安装和使用 在PC机上安装SPSS软件,打开软件: 基本统计分析功能包括描述统计和行列计算,还包括在基本分析中最受欢迎的常见统计功能,如汇总、计数、交叉分析、分类比较、描述性统计、因子分析、回归分析及聚类分析等等。具体如下: 1.数据访问、数据准备、数据管理与输出管理; 2.描述统计和探索分析:频数、描述、集中趋势和离散趋势分析、分布分析与查看、正态性检验与正态转换、均值的置信区间估计; 3.交叉表:计数;行、列和总计百分比;独立性检验;定类变量和定序变量的相关性测度; 4.二元统计:均值比较、T检验、单因素方差分析; 5.相关分析:双变量相关分析、偏相关分析、距离分析; 6.线性回归分析:自动线性建模、线性回归、Ordinal回归—PLUM、曲线估计; 7.非参数检验:单一样本检验、双重相关样本检验、K重相关样本检验、双重独立样本检验、K重独立样本检验; 8.多重响应分析:交叉表、频数表; 9.预测数值结果和区分群体:K-means聚类分析、分级聚类分析、两步聚类分析、快速聚类分析、因子分析、主成分分析、最近邻元素分析; 10. 判别分析; 11.尺度分析; 12. 报告:各种报告、记录摘要、图表功能(分类图表、条型图、线型图、面积图、高低图、箱线图、散点图、质量控制图、诊断和探测图等); 13.数据管理、数据转换与文件管理; 二.数据文件的处理 SPSS数据文件是一种结构性数据文件,由数据的结构和数据的内容两部分构成,也可以说由变量和观测两部分构成。定义一个变量至少要定义它的两个属性,即变量名和变量类型其他属性可以暂时采用系统默认值,待以后分析过程中如果有需要再对其进行设置。在spss数据编辑窗口中单击“变量视窗”标签,进入变量视窗界面,即可对变量的各个属性进行设置。 1.创建一个数据文件数据 (1)选择菜单【文件】→【新建】→【数据】新建一个数据文件,进入数据编辑窗口。窗口顶部标题为“PASW Statistics数据编辑器”。 (2)单击左下角【变量视窗】标签进入变量视图界面,根据试验的设计定义每个变量类型。

操作系统(一个小型操作系统的设计与实现)课程设计

南通大学计算机科学与技术学院操作系统课程设计报告 专业: 学生姓名: 学号: 时间:

操作系统模拟算法课程设计报告 设计要求 将本学期三次的实验集成实现: A.处理机管理; B.存储器管理; C.虚拟存储器的缺页调度。 设计流程图 主流程图 开始的图形界面 处理机管理存储器管理缺页调度 先来先服务时 间 片 轮 转 首 次 适 应 法 最 佳 适 应 法 先 进 先 出 L R U 算 法

A.处理机调度 1)先来先服务FCFS N Y 先来先服务算法流程 开始 初始化进程控制块,让进程控制块按进程到达先后顺序让进程排队 调度数组中首个进程,并让数组中的下一位移到首位 计算并打印进程的完成时刻、周转时间、带权周转时间 其中:周转时间 = 完成时间 - 到达时间 带权周转时间=周转时间/服务时间 更改计时器的当前时间,即下一刻进程的开始时间 当前时间=前一进程的完成时间+其服务时间 数组为空 结束

2)时间片轮转法 开始 输入进程总数 指针所指的进程是 否结束 输入各进程信息 输出为就绪状态的进程的信息 更改正在运行的进程的已运行时间 跳过已结束的程序 结束 N 指向下一个进程 Y 如果存在下一个进程的话 Y N 输出此时为就绪状态的进程的信息 时间片轮转算法流程图

B.存储器管理(可变式分区管理) 1)首次适应法 分配流程图 申请xkb内存 由链头找到第一个空闲区 分区大小≥xkb? 大于 分区大小=分区大小-xkb,修改下一个空闲区的后向指针内容为(后向指针)+xkb;修改上一个空闲区的前向指针为(前向指针)+xkb 将该空闲区从链中摘除:修改下一个空闲区的后向地址=该空闲区后向地址,修改上一个空闲区的前向指针为该空闲区的前向指针 等于 小于延链查找下 一个空闲区 到链尾 了? 作业等待 返回是 否 登记已分配表 返回分配给进程的内存首地址 开始

操作系统课程设计题目

实验一进程调度 一、实验目的 观察、体会Linux 系统的进程调度方法,并通过一个简单的进程调度模拟程序的实现,加深对进程调度算法,进程切换的理解。 二、实验内容 采用动态优先数的方法,编写一进程调度程序模拟程序。模拟程序只进行相应的调度模拟操作,不需要实际程序。 [提示]: (1) 假定系统有五个进程,每一个进程用一个进程控制块PCB来代表,进程控制块的格式为: 进程名 指针 要求运行时间 优先数 状态 其中,进程名——作为进程的标识,假设五个进程的进程名分别为P1,P2,P3,P4,P5。 指针——按优先数的大小把五个进程连成队列,用指针指出下一个进程的进程控制块的首地址,最后一个进程中的指针为“0”。 要求运行时间——假设进程需要运行的单位时间数。 优先数——赋予进程的优先数,调度时总是选取优先数大的进程先执行。 状态——可假设有两种状态,“就绪”状态和“结束”状态。五个进程的初始状态都为“就绪”,用“R”表示,当一个进程运行结束后,它的状态为“结束”,用“E”表示。 (2) 在每次运行你所设计的处理器调度程序之前,为每个进程任意确定它的“优先数”和“要求运行时间”。 (3) 为了调度方便,把五个进程按给定的优先数从大到小连成队列。用一单元指出队首进程,用指针指出队列的连接情况。 (4) 处理器调度总是选队首进程运行。采用动态改变优先数的办法,进程每运行一次优先数就减“1”。由于本实习是模拟处理器调度,所以,对被选中的进程并不实际的启动运行,而是执行: 优先数-1 要求运行时间-1 来模拟进程的一次运行。 提醒注意的是:在实际的系统中,当一个进程被选中运行时,必须恢复进程的现场,让它占有处理器运行,直到出现等待事件或运行结束。在这里省去了这些工作。 (5) 进程运行一次后,若要求运行时间?0,则再将它加入队列(按优先数大小插入,且置队首标志);若要求运行时间=0,则把它的状态修改成“结束”(E),且退出队列。 (6) 若“就绪”状态的进程队列不为空,则重复上面(4)和(5)的步骤,

操作系统课程设计报告

操作系统课程设计实验报告 实验名称:进程控制 姓名/学号: 一、实验目的 学习、理解和掌握Linux与windows的进行控制系统调用的功能,熟悉主要的几个系统调用命令的格式和如何利用系统调用命令进行编程。通过学习,理解如何创建一个进程、改变进程执行的程序、进程和线程终止以及父子进程的同步等,从而提高对进程和线程控制系统调用的编程能力。 二、实验内容 设计并实现Unix的“time”命令。“mytime”命令通过命令行参数接受要运行的程序,创建一个独立的进程来运行该程序,并记录程序运行的时间。 三、实验环境 CPU: Inter ×2 2.10GHz RAM: 3.00GB Windows 7 旗舰版 Linux Ubuntu 10.04 编译: VS2010 四、程序设计与实现 4.1进程控制系统的调用 4.1.1 windows进程控制调用程序中使用的数据结构及主要符号说明 SYSTEMTIME starttime,endtime; //进程开始时间和结束时间 PROCESS_INFORMATION pi //该结构返回有关新进程及 //其主线程的信息 STARTUPINFO si //该结构用于指定新进程的主窗口特性4.1.2 linux进程控制调用程序中使用的数据结构及主要符号说明 struct timeval starttime,endtime //进程开始时间和结束时间 pid_t pid //进程标志符

4.2 程序流程图 图1 windows进程控制调用图2 linux进程控制调用程序运行流程图程序运行流程图 五、实验结果和分析 5.1 windows实验结果和分析

相关主题