操作系统课程设计

更新时间:2023-09-17 02:52:01 阅读量: 高中教育 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

JI A N G S U U N I V E R S I T Y

《操作系统》课程设计

题目:进程通信与进程同步机制实践

学院名称: 计算机科学与通信工程学院 班级学号: 学生姓名:

教师姓名: 教师职称:

2016年 1 月8日

目录

一 课程设计内容

二 开发环境 二 原理

五 主要数据结构和流程

六 原语对应的函数及算法

七 测试结果与分析 八 总结

九 源程序清单

一课程设计的内容

【设计内容】

某银行提供6个服务窗口(3个对私服务窗口,2个对公服务窗口,1个理财服务窗口、一台取号机和20个供顾客等待的座位。顾客到达银行时,若有空座位,则到取号机上领取一个号,等待叫号;若没有空座位,则在门外等待或离开。取号机每次仅允许一位顾客使用,有对公、对私和理财三类号,每位顾客只能选取其中一个。当营业员空闲时,通过叫号选取一位顾客,并为其服务。 【说明】

(1)可模拟设立一个服务时间区间如9:00-17:00,也可限定最大服务人数; (2)顾客达到时间随机,办理对私、对公、理财业务随机,每位顾客服务时间可设定在一定范围内。这些都可通过随机数产生。

(3)取号时顾客拿到的号含有号码和等待的人数,例如A、B、C分别代表对私、对公、理财,“号码:A05,有2人等待”表示取的是对私服务号,编号是05,有2人等待办理对私业务。

(4)成绩评定:平时占60%,实验报告占40%;其中平时60%包括考勤和学习态度、学习积极性等占20%,两次检查,每次检查各占20%。

【检查说明】

第一次检查:时间18周周三-四,检查同步与互斥算法与API熟悉情况

第二次检查:时间18周周五上午与晚上,检查最终程序完成情况。

【要求】

1、说明设置哪些信号量?信号量的含义和初始值是什么?并用信号量和P、V操作写出进程的同步算法。(注:该内容包含在设计报告中,并在第一次检查时检查)

2、查阅并自学进程、线程的创建与撤销、信号量、P操作、V操作等相关原语的系统调用。(注:该内容包含在设计报告中,并在第一次检查时检查) 3、在Linux或Windows或Unix环境下,采用系统调用中的进程或线程的创建与撤销、信号量、P操作、V操作,编程解决上述问题,并完成调试与测试工作。(注:该内容包含将并在第二次检查时检查)

4、打印:(注意:由于多个进程共享一个显示器或文件,需要互斥访问)

各进程的初始状态信息; 中间状态变化信息; 最终状态信息。

例如,顾客到达时的时间状态信息,领取的号码信息,等待时间,接收服务的服务窗口信息、服务时间,离开时间等信息。 目的

通过课程设计模拟银行办理业务的情景,使用pv操作实现互斥与同步。来进一步熟悉课堂上讲授的pv操作原语,掌握进程的互斥与同步的知识。

二开发环境

windows操作系统,

使用Java语言, 在eclipse上实现

三原理及算法

1用一个线程来模拟一位客户,客户到来时间,离开时间,都是通过获取系统的时间来体现。中间等待及办理业务的时间则通过产生的一定范围的随机数对线程进行睡眠来模拟的 2总共分为三个类,

第一个类是包括主函数的类,用来开启程序并创建线程对象。 第二个类是线程类,包括线程的定义和线程的方法run方法,在run方法内对实现主要程序的功能的函数进行调用。

第三个类,就是存储的需要用到的主要变量,计数器,及实现程序功能的三个函数,供所有的线程公用。三个函数。

第一个函数进行座位的检测,有座位则进入银行,没有在在外等待,以及获取此时运行该线程的名字,作为一个客户的标识,并通告该客户到来及此时的时间。 第二个函数实现取号功能,其中包括判断取号机是否有人使用,取号时根据随机数产生三种不同的票号,同时该票号的内容还包括票的序号和此类票号对应的服务窗口现在还有多少人在等待。 第三个函数是服务功能,包括根据票号判断此时该类窗口是否有已满,满了就等待,没满则去办理业务。办理业务通过产生随机数对线程进行休眠,客户离开时,通告客户的服务时间,及离开的时间。

四主要数据结构和流程

六个信号量

一个代表大厅的座位,初值为20。 一个代表取号机,初值为1,。 三个窗口,初值分别为3,2,1。

一个用来实现对记录大厅人数的变量的互斥操作。 四个变量

一个代表办理业务的总人数。

三个分别代表三个窗口的等待人数。 票号的格式为服务+票号+等待人数。例如A-22-3表示办理对私服务,票号为22,该窗口还有3人在等待。

等待时间,服务时间,均是调用函数产生随机数。 流程图

五原语对应函数及pv算法

创建线程:继承Thread类,实现run方法 信号量semaphore p操作:acquire v操作:release

Semaphore Zcount ,Qcount,counta,countb,countc,countx; Zcount.value=20; Qcount.value=1; Counta.value=3; Countb.value=2; Countc.value=1; Countx.value=1; Process{ P(&zcount);{

p(&qcount); 取票 A B C

Return A或者B或者C; v(&qcount); If(A){

P(&counta); V(&zcount); 办理服务 V(&counta); }

Else if(B){ P(&countb); V(&zcount); 办理服务 V(&countb); } Else{

P(&countc); V(&zcount); 办理服务 V(&countc); } } }

六测试结果与分析

分析:进程的名字标志客户。

由于线程太快,设置的休眠时间较短,所以存在同一秒级有多个用户到达。 服务时间为1000,2000,3000毫秒随机。 到来及离开都是分别获取此时系统的时间。

七总结

经过本次的实验对pv操作有了更进一步的理解,从更深层次了解了同步与互斥的原理及实现的过程。设计过程遇到了各种问题。

在设计pv操作时由于座位加上窗口共可以存放26个人,尽管信号量设置的是20,但是需要在每一个人申请到窗口时即释放座位。就是在释放窗口之前。 在设计程序时关于每个线程共享的变量以及每个线程私有的变量的问题,比如取到的号即为每个线程的私有变量。 最后经过一周半的课程设计之后,对编程,解决问题的能力,都有了一定的提升。

九 源程序清单

第一个类

package bank1;

publicclass routine {

publicstatic common comm =new common(); }

@SuppressWarnings(\) publicstaticvoid main(String[] args) { }

inti;

for (i=1;i<=20;i++){

client clii=new client(comm); clii.start(); }

第二个类

package bank1; import bank1.common; import java.util.Random;

import java.util.concurrent.Semaphore; public class client extends Thread { private common comm;

String result= new String();

public client(common thiscomm) { }

Random ran=new Random(); try { }

comm.sit(this.getName()); result=comm.qu(this.getName());

sleep((ran.nextInt(6)+1)*2000); // TODO 自动生成的 catch 块 e1.printStackTrace();

} catch (InterruptedException e1) {

// TODO 自动生成的构造函数存根 comm=thiscomm;

public void run(){

} }

comm.handle(result, this.getName()); try { }

sleep(10);

// TODO 自动生成的 catch 块 e.printStackTrace();

} catch (InterruptedException e) {

第三个类

package bank1;

import java.util.Date; import java.util.Random;

import java.util.concurrent.Semaphore; publicclass common {

privateintzcount; privateintaa,bb,cc;

Semaphore semaphore = new Semaphore(10); Semaphore semaphoreq = new Semaphore(1); Semaphore semaphorea = new Semaphore(3); Semaphore semaphoreb = new Semaphore(2); Semaphore semaphorec = new Semaphore(1); Semaphore semaphorez = new Semaphore(1); Random ran1=new Random(); public common(){

zcount=1; aa=-3; bb=-2; cc=-1;

}

publicvoid sit(String name){ try { }

Date date=new Date();

semaphore.acquire(); // TODO 自动生成的 catch 块 e.printStackTrace();

} catch (InterruptedException e) {

System.out.println(\客户:\+name+\在时间\+date.toString()+\:到达\+\);

}

String a= new String(); try {

public String qu(String name) {

} }

semaphoreq.acquire(); // TODO 自动生成的 catch 块 e.printStackTrace(); intx; inty;

Random ran=new Random(); x=ran.nextInt(9); y=zcount;

//System.out.println(x); aa++; intaaa; if (aa<0) aaa=0;

else{aaa=aa;}

a=\+\+y+\该服务有\+aaa+\人等待\;

System.out.println(\客户:\+name+\取到号:\+a+\); try { }

zcount++;

semaphorez.release();

semaphorez.acquire(); // TODO 自动生成的 catch 块 e.printStackTrace();

} catch (InterruptedException e) {

} catch (InterruptedException e) {

if(x<3){

elseif(3<=x&&x<=6){

bb++; intbbb; if (bb<0) bbb=0;

else{bbb=bb;}

a=\+\+y+\该服务有\+bbb+\人等待\;

System.out.println(\客户:\+name+\取到号:\+a+\); try { }

zcount++;

semaphorez.release();

semaphorez.acquire(); // TODO 自动生成的 catch 块 e.printStackTrace();

} catch (InterruptedException e) {

} else{ }

semaphoreq.release(); returna; }

if (b.charAt(0)=='A'){ try { }

semaphore.release();

semaphorea.acquire(); // TODO 自动生成的 catch 块 e.printStackTrace();

} catch (InterruptedException e) {

cc++; intccc; if (cc<0) ccc=0;

else{ccc=cc;}

a=\+\+y+\该服务有\+ccc+\人等待\;

System.out.println(\客户:\+name+\取到号:\+a+\); try { }

zcount++;

semaphorez.release();

semaphorez.acquire(); // TODO 自动生成的 catch 块 e.printStackTrace();

} catch (InterruptedException e) {

publicvoid handle(String b ,String name){

System.out.println(name+\:正在对私服务窗口办理业务\+\); intt=(ran1.nextInt(3)+1)*1000; try { } aa--;

semaphorea.release(); Date date=new Date();

System.out.println(name+\服务时间\+t+\毫秒在\+date+\:离开\+\); }

elseif(b.charAt(0)=='B'){ Thread.sleep(t);

// TODO 自动生成的 catch 块

e.printStackTrace();

} catch (InterruptedException e) {

try { }

semaphore.release();

semaphoreb.acquire(); // TODO 自动生成的 catch 块 e.printStackTrace();

} catch (InterruptedException e) {

System.out.println(name+\:正在对公服务窗口办理业务\+\); intt=(ran1.nextInt(3)+1)*1000; try { } bb--;

semaphoreb.release(); Date date=new Date();

Thread.sleep(t);

// TODO 自动生成的 catch 块 e.printStackTrace();

} catch (InterruptedException e) {

System.out.println(name+\服务时间\+t+\毫秒在\+date+\:离开\+\); }

elseif(b.charAt(0)=='C') {

try { }

semaphore.release();

System.out.println(name+\:正在理财服务窗口办理业务\+\); intt=(ran1.nextInt(3)+1)*1000; try { } cc--;

semaphorec.release(); Date date=new Date();

Thread.sleep(t);

// TODO 自动生成的 catch 块 e.printStackTrace();

} catch (InterruptedException e) {

semaphorec.acquire(); // TODO 自动生成的 catch 块 e.printStackTrace();

} catch (InterruptedException e) {

System.out.println(name+\服务时间\+t+\毫秒在\+date+\:离开\+\); } } }

附件 检查一

1信号量的含义初值? zcount座位,初值20。 qcount取号机,初值1。 Counta A类窗口,初值3。 Countb B类窗口,初值2。 Countc C类窗口,初值1。 Countx 计数器互斥操作,初值1。 2 pv原语对应的api? Java语言

信号量 semaphore P :acquire V : release 线程创建 继承Thread类 实现run方法

3 是否要区分窗口,每一个窗口都设置一个信号量?

不需要,可将每一种窗口化为一类,判断有无空闲即可,有则服务,没有则等待。 检查二

1是否设置服务时间,或最大服务量?

根据作业要求该功能是可选模块,可以选择是否实现, 本作业有实现可以加一个if else 判断是否在服务时间段内,如在则允许创建线程对象,如不在,则禁止创建,并输出“不在服务时间范围内”。

2开始客户到来的时间是随机的吗?

是,在创建每个线程之后,调用start之前前产生随机数,并且根据随机数进行线程休眠,这样可以模拟客户的随机到来,但是由于线程运行太块,为了方便展示实现效果,将休眠的时间设置为妙级的,所以随机的到来时间只是秒数或者分钟不同。 3 三个状态是否有体现?

有,开始,有客户名字,到来时间,即创建线程时的系统时间,通过时间类的对象获取并输出。

中间有取到的票号,包括类别,号码,等待人数,还有服务的时间,也是随机数线程休眠。并且输出。

结束的时候有客户离开的时间,也是离开时候的系统时间。

本文来源:https://www.bwwdw.com/article/wioh.html

Top