操作系统课程设计报告lxx
更新时间:2023-10-14 18:02:01 阅读量: 综合文库 文档下载
江苏大学
《操作系统》课程设计说明书
设计题目 进程通信与进程同步机制实践 学生姓名
指导老师 薛安荣 学 院 计算机学院 专业班级 软件工程1202班 学号
完成时间 2015年1月2日
一. 课程设计题目
某银行提供5个服务窗口(3个对私服务窗口,1个对公服务窗口,1个理财服务窗口)和10个供顾客等待的座位。顾客到达银行时,若有空座位,则到取号机上领取一个号,等待叫号;若没有空座位,则在门外等待或离开。取号机每次仅允许一位顾客使用,有对公、对私和理财三类号,每位顾客只能选取其中一个。当营业员空闲时,通过叫号选取一位顾客,并为其服务。请用P、V操作写出进程的同步算法。
(1)可限定最大服务人数
(2)办理对私、对公、理财业务随机,可通过随机数产生。 (3)取号时顾客拿到的号含有号码和显示当前等待人数,例如A、B、C分别代表对私、对公、理财,“号码:A5”表示取的是对私服务号,编号是5。
二.课程设计目的
1、掌握基本的同步与互斥算法,理解银行排队系统操作模型。 2、学习使用Windows7中基本的同步对象,掌握相关API的使用方法。
3、了解Windows7中多线程的并发执行机制,实现进程的同步与互斥。
三.课程设计要求
◆学习并理解生产者/消费者模型及其同步/互斥规则;
◆学习了解Windows同步对象及其特性; ◆熟悉实验环境,掌握相关API的使用方法;
◆设计程序,实现生产者/消费者进程(线程)的同步与互斥; ◆提交实验报告。
四.需要了解的知识
1.同步对象
同步对象是指Windows中用于实现同步与互斥的实体,包括信号量(Semaphore)、互斥量(Mutex)、临界区(Critical Section)和事件(Events)等。本实验中使用到信号量、互斥量和临界区三个同步对象。
2.同步对象的使用步骤:
◆创建/初始化同步对象。
◆请求同步对象,进入临界区(互斥量上锁)。 ◆释放同步对象(互斥量解锁)。
五.需要用到的API函数及相关函数
我们利用Windows SDK提供的API编程实现实验题目要求,而VC中包含有Windows SDK的所有工具和定义。要使用这些API,需要包含堆这些函数进行说明的SDK头文件——最常见的是Windows.h(特殊的API调用还需要包含其他头文件)。
本实验使用到的API的功能和使用方法简单介绍 1、WaitForSingleObject(cs1,INFINITE); ? WaitForSingleObject(seat,INFINITE);
? WaitForSingleObject(mutex,INFINITE);
? 功能——对请求服务顾客,座位和互斥量信号量进行P操作 ? 格式
DWORD WINAPI WaitForSingleObject(
_In_ HANDLE hHandle, _In_ DWORD dwMilliseconds ); ? 参数说明
hHandle——信号量指针。
dwMilliseconds——等待的最长时间(INFINITE为无限等待)。 2、ReleaseMutex( mutex );
? 功能——打开互斥锁,即把互斥量加1。成功调用则返回0 ? 格式
BOOL WINAPI ReleaseMutex(
_In_ HANDLE hMutex); ? 参数说明 hMutex——互斥量
3. ReleaseSemaphore(s3,1,NULL); ReleaseSemaphore(cs1,1,NULL); ReleaseSemaphore(seat,1,NULL);
? 功能——对窗口,顾客,座位信号量进行V操作 ? 格式
BOOL WINAPI ReleaseSemaphore(
_In_ HANDLE hSemaphore, _In_ LONG lReleaseCount, _Out_opt_ LPLONG lpPreviousCount ); ? 参数说明
hSemaphore——信号量指针。 lReleaseCount——信号量的增量。 lppreviousCount——保存信号量当前值。
4、CreateThread(NULL,0,consumer1,NULL,0,NULL); ? 功能——创建一个在调用进程的地址空间中执行的线程 ? 格式
HANDLE WINAPI CreateThread(
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ SIZE_T dwStackSize,
_In_ LPTHREAD_START_ROUTINE lpStartAddress, _In_opt_ __drv_aliasesMem LPVOID lpParameter, _In_ DWORD dwCreationFlags, _Out_opt_ LPDWORD lpThreadId); ? 参数说明
lpThreadAttributes——指向一个LPSECURITY_ATTRIBUTES(新线程的安全性描述符)。
dwStackSize——定义原始堆栈大小。
lpStartAddress——指向使用LPTHRAED_START_ROUTINE类型
定义的函数。
lpParamiter——定义一个给进程传递参数的指针。 dwCreationFlags——定义控制线程创建的附加标志。 lpThread——保存线程标志符(32位)
5、mutex = CreateMutex(NULL,FALSE,NULL); ? 功能——创建一个命名或匿名的互斥量对象 ? 格式
HANDLE WINAPI CreateMutexW(
_In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes, _In_ BOOL bInitialOwner,
_In_opt_ LPCWSTR lpName); ? 参数说明
lpMutexAttributes——必须取值NULL。
bInitialOwner——指示当前线程是否马上拥有该互斥量(即马上加锁)。
lpName——互斥量名称。
5. seat = CreateSemaphore(NULL,Seat , Seat, NULL); ? 功能——创建一个命名或匿名的信号量对象 ? 格式
HANDLE WINAPI CreateSemaphoreW(
_In_opt_ LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, _In_ LONG lInitialCount,
_In_ LONG lMaximumCount, _In_opt_ LPCWSTR lpName); ? 参数说明
lpSemaphoreAttributes——必须取值NULL。
lInitialCount——信号量的初始值。该值大于0,但小于lMaximumCount指定的最大值。 lpName——信号量名称。
六.原理及算法
1、信号量设置
seat:座位信号量 s1:对私服务窗口的信号量 s2:对公服务窗口的信号量 s3:理财服务窗口的信号量
cs1:请求对私服务窗口的客户的信号量 cs2:请求对公服务窗口的客户的信号量 Cs3:请求理财服务窗口的客户的信号量 mutex:取号机互斥信号量
c1[Customer_num]:请求对私服务顾客线程信号量 c2[Customer_num]:请求对公服务顾客线程信号量 c3[Customer_num]:请求理财服务顾客线程信号量
ss1[StaticServer]:窗口对私服务信号量 ss2[PublicServer]:窗口对公服务信号量 ss3[FinancialService]:窗口理财服务信号量
2、线程创建
StaticServer 3:3个对私窗口线程 PublicServer 1:1个对私窗口线程 FinancialService 1:1个理财窗口线程 consumer1:对私顾客线程 consumer2:对公顾客线程 Consumer3:理财顾客线程 server1:窗口对私线程 Server2:窗口对公线程 Server3:窗口理财线程
3、P、V操作
DWORD WINAPI server1(PVOID s1pv) //窗口对私线程代码 {
while(true) {
WaitForSingleObject(cs1,INFINITE);//p(&cs1)对私顾客-1 Sleep(ServeTime);//运行一个窗口服务时间
EnterCriticalSection(&x);//进入临界区,窗口不允许其他
顾客进入
cout<<\对私窗口叫号!\< LeaveCriticalSection(&x);//离开临界区 ReleaseSemaphore(s1,1,NULL);//v(&s1)释放对私窗口+1 EnterCriticalSection(&c_seat);//进入临界区,座位不共享 seat_num++;//可用座位+1 LeaveCriticalSection(&c_seat);离开临界区 } return 0; } Server2//营业员对公窗口线程代码相似 Server3//营业员理财窗口线程代码相似 /*******************取号同一时间最多一个******************/ WaitForSingleObject(mutex,INFINITE);//p(&mutex)互斥量 P操作 EnterCriticalSection(&x);//进入临界区 cout<<\顾客\< ReleaseSemaphore(cs1,1,NULL);//v(&cs1)释放1对私顾客 七. 算法流程图 八. 开始 客户到达 是 座位满? 离开? 是 离开 否 否 门口等待 是 服务人数满? 否 排队取号 是 否 窗口闲置? 服务并离开 结束 八.主要数据结构及实现 通过创建8个线程来实现银行排队系统,3个对私窗口,1个对公窗口,1个理财窗口,1个对私等待顾客,1个对公等待顾客, 1个理财等待顾客。8个窗口建立之后,来顾客就执行,没顾客就挂起,进入等待状态,通过设计一个随机数来实现五分之三的几率进行对私服务,五分之一的几率进行对公服务,五分之一的几率进行理财服务,服务时间固定,取号机只能一个人用,所以设置了mutex互斥信号量。门口来人时,先检查座位是否满了,没满,则取号,进入等待室,然后等待窗口叫号,当服务完时,离开并释放一个座位。若座位满了,设置了伪随机数实现二分之一的几率选择留下等待或离开。 窗口线程创建过程:(窗口线程分对公顾客线程、对私顾客线程和理财顾客线程,创建过程基本类似,下面列举对私顾客线程创建过程) DWORD WINAPI server1(PVOID s1pv) //窗口对私线程代码 { while(true) { WaitForSingleObject(cs1,INFINITE);//p(&cs1)对私顾客-1 Sleep(ServeTime);//运行一个窗口服务时间 EnterCriticalSection(&x);//进入临界区,窗口不允许其他顾客进入 cout<<\对私窗口叫号!\< LeaveCriticalSection(&x);//离开临界区 ReleaseSemaphore(s1,1,NULL);//v(&s1)释放对私窗口+1 EnterCriticalSection(&c_seat);//进入临界区,座位不共享 } } seat_num++;//可用座位+1 LeaveCriticalSection(&c_seat);离开临界区 return 0; 顾客线程创建过程:(窗口线程分3个对私窗口、1个对公窗口和1个理财窗口,创建过程基本类似,下面列举对公窗口1线程创建过程) DWORD WINAPI consumer1(PVOID c1pv)//顾客对私线程代码 { cout<<\这是第\< srand((unsigned)time(0));//伪随机数 int n=rand()%2; { //离开 } else if(seat_num<=0) { //留下等待 } EnterCriticalSection(&c_seat); seat_num--;//可用座位数-1 LeaveCriticalSection(&c_seat); //WaitForSingleObject(seat,INFINITE);//p(&seat) WaitForSingleObject(mutex,INFINITE);//p(&mutex) 取号在临界区操作 EnterCriticalSection(&nu1); number1++; //对私服务的顾客取号得到的编号+1 LeaveCriticalSection(&nu1); //EnterCriticalSection(&y); number++;//服务人数+1 //LeaveCriticalSection(&y); m1++;//取号时显示当前等待人数+1 int temp1=number1; EnterCriticalSection(&coun); amount ++;//门外等待人数+1 LeaveCriticalSection(&coun); EnterCriticalSection(&x); cout<<\该顾客在门外等待,已有\< cout<<\座位已满,该顾客离开!\< if(seat_num<=0&&n==1) Sleep(ServeTime);//服务完一个顾客 m1--;//当前等待人数—1 ReleaseSemaphore(seat,1,NULL);//v(&seat) EnterCriticalSection(&c_seat); seat_num++;//可用座位+1 LeaveCriticalSection(&c_seat); if(seat_num<=0)//判断座位是否够 { } EnterCriticalSection(&x); cout<<\顾客A\< EnterCriticalSection(&x); cout<<\门外还剩\< EnterCriticalSection(&x); cout<<\顾客\<<\< Sleep(ServeTime);//休眠一段时间 WaitForSingleObject(s1,INFINITE);//p(&s1) EnterCriticalSection(&x); cout<<\顾客A\< ReleaseMutex(mutex);//v(&mutex) ReleaseSemaphore(cs1,1,NULL);//v(&cs1) 释放一个对私窗口 EnterCriticalSection(&x); cout<<\顾客\< 私服务\< } 九.实验测试结果及结果分析 结果分析 顾客进入银行之前,首先判断是否有空座位,若有,则在取号机上取号,等待窗口服务,若没有随机选择去留。对于窗口而言,只要其空闲,则按照顾客取号的顺序为顾客提供服务。所有线程执行结束之后程序结束。 十.课程设计总结 通过此次课程设计,使我更加充分的掌握了有关操作系PV操作,在设计过程中虽然遇到了一些问题,但经过一次又一次的思考,一遍又一遍的检查终于找出了原因所在,也暴露出了前期我在这方面的知识欠缺和经验不足。在课程设计过程中,我们不断发现错误,不断改正,不断领悟,本身就是在践行“过而能改,善莫大焉”的知行观。这次课程设计终于顺利完成了,在设计中遇到了很多问题,最后在老师和同学的指导下,终于游逆而解。在这学期的实验中,不仅培养了独立思考、动手操作的能力,在各种其它能力上也都有了提高。更重要的是,在实验课上,我们学会了很多学习的方法。而这是日后最实用的,真的是受益匪浅。要面对社会的挑战,只有不断的学习、实践,再学习、再实践。这对于我们的将来也有很大的帮助。以后,不管有多苦,我想我们都能变苦为乐,找寻有趣的事情,发现其中珍贵的事情。就像中国提倡的艰苦奋斗一样,我们都可以在实验结束之后变的更加成熟,会面对需要面对的事情。 十一.源程序清单 主要代码 #include\ #include \ #include //私有服务 #define PublicServer 1 //公有服务 #define FinancialService 1 //理财服务 #define Seat 10 //座位量 #define ServeTime 2000 //服务时间 //顾客数量 //顾客来的最大间隔时间 #define Customer_num 50 #define Customer_time 500 //取号号码 int number = 0; int number1 = 0,m1=0; int number2 = 0,m2=0; int number3 = 0,m3=0; int seat_num=10; int amount =0; //创建句柄 HANDLE seat,s1,s2,s3,cs1,cs2,cs3; HANDLE mutex; HANDLE c1[Customer_num],c2[Customer_num],c3[Customer_num],ss1[StaticServer],ss2[PublicServer],ss3[FinancialService]; CRITICAL_SECTION c_seat; CRITICAL_SECTION x; CRITICAL_SECTION coun; CRITICAL_SECTION nu1; CRITICAL_SECTION nu2; CRITICAL_SECTION nu3; DWORD WINAPI server1(PVOID s1pv) //窗口对私线程代码 { } DWORD WINAPI server2(PVOID s2pv) //窗口对公线程代码 { while(true) { WaitForSingleObject(cs2,INFINITE);//p(&cs2) Sleep(ServeTime); EnterCriticalSection(&x); cout<<\对公窗口叫号!\< WaitForSingleObject(cs1,INFINITE);//p(&cs1) Sleep(ServeTime); EnterCriticalSection(&x); cout<<\对私窗口叫号!\< ReleaseSemaphore(s1,1,NULL);//v(&s1) EnterCriticalSection(&c_seat); seat_num++; LeaveCriticalSection(&c_seat); //临界区,防止重叠 //互斥量 //座位数,对私服务窗口,对公服务窗口,对理财服务 窗口,进行对私服务顾客,进行对公服务顾客,进行对理财服务顾客 } } LeaveCriticalSection(&x); ReleaseSemaphore(s2,1,NULL);//v(&s2) EnterCriticalSection(&c_seat); seat_num++; LeaveCriticalSection(&c_seat); return 0; DWORD WINAPI server3(PVOID s3pv) //窗口对理财线程代码 { } DWORD WINAPI consumer1(PVOID c1pv)//顾客对私线程代码 { cout<<\这是第\< srand((unsigned)time(0)); int n=rand()%2; { } else if(seat_num<=0) { } EnterCriticalSection(&coun); amount ++; LeaveCriticalSection(&coun); EnterCriticalSection(&x); cout<<\该顾客在门外等待,已有\< cout<<\座位已满,该顾客离开!\< while(true) { } return 0; WaitForSingleObject(cs3,INFINITE);//p(&cs3) Sleep(ServeTime); EnterCriticalSection(&x); cout<<\对理财窗口叫号!\< ReleaseSemaphore(s3,1,NULL);//v(&s3) EnterCriticalSection(&c_seat); seat_num++; LeaveCriticalSection(&c_seat); if(seat_num<=0&&n==1) EnterCriticalSection(&c_seat); seat_num--; LeaveCriticalSection(&c_seat); //WaitForSingleObject(seat,INFINITE);//p(&seat) WaitForSingleObject(mutex,INFINITE);//p(&mutex) EnterCriticalSection(&nu1); number1++; LeaveCriticalSection(&nu1); //EnterCriticalSection(&y); number++; //LeaveCriticalSection(&y); m1++; int temp1=number1; EnterCriticalSection(&x); cout<<\顾客\< cout<<\顾客A\< WaitForSingleObject(s1,INFINITE);//p(&s1) EnterCriticalSection(&x); cout<<\顾客\<<\< ReleaseSemaphore(seat,1,NULL);//v(&seat) EnterCriticalSection(&c_seat); seat_num++; LeaveCriticalSection(&c_seat); if(seat_num<=0) { EnterCriticalSection(&x); cout<<\门外还剩\< 私服务\< } } EnterCriticalSection(&x); cout<<\顾客A\< DWORD WINAPI consumer2(PVOID c2pv)//顾客对公线程代码 { EnterCriticalSection(&x); cout<<\顾客\< //WaitForSingleObject(seat,INFINITE);//p(&seat) WaitForSingleObject(mutex,INFINITE);//p(&mutex) EnterCriticalSection(&nu2); number2++; LeaveCriticalSection(&nu2); //EnterCriticalSection(&y); number++; //LeaveCriticalSection(&y); m2++; int temp2=number2; cout<<\这是第\< srand((unsigned)time(0)); int n=rand()%2; if( seat_num<=0&&n==1) { } else if(seat_num<=0) { } EnterCriticalSection(&c_seat); seat_num--; LeaveCriticalSection(&c_seat); EnterCriticalSection(&coun); amount ++; LeaveCriticalSection(&coun); EnterCriticalSection(&x); cout<<\该顾客在门外等待,已有\< cout<<\座位已满,该顾客离开!\< 公服务\< } LeaveCriticalSection(&x); ReleaseMutex(mutex);//v(&mutex) ReleaseSemaphore(cs2,1,NULL);//v(&cs2) EnterCriticalSection(&x); cout<<\顾客B\< WaitForSingleObject(s2,INFINITE);//p(&s2) EnterCriticalSection(&x); cout<<\顾客B\< ReleaseSemaphore(seat,1,NULL);//v(&seat) EnterCriticalSection(&c_seat); seat_num++; LeaveCriticalSection(&c_seat); if(seat_num<=0) { } EnterCriticalSection(&x); cout<<\顾客B\< EnterCriticalSection(&x); cout<<\门外还剩\< DWORD WINAPI consumer3(PVOID c3pv)//顾客对理财线程代码 { cout<<\这是第\< srand((unsigned)time(0)); int n=rand()%2; if( seat_num<=0&&n==1) { EnterCriticalSection(&x); cout<<\座位已满,该顾客离开!\< } else if(seat_num<=0) { } EnterCriticalSection(&c_seat); seat_num--; LeaveCriticalSection(&c_seat); //WaitForSingleObject(seat,INFINITE);//p(&seat) WaitForSingleObject(mutex,INFINITE);//p(&mutex) EnterCriticalSection(&nu3); number3++; LeaveCriticalSection(&nu3); //EnterCriticalSection(&y); number++; //LeaveCriticalSection(&y); m3++; int temp3=number3; EnterCriticalSection(&x); cout<<\顾客\< cout<<\顾客C\< WaitForSingleObject(s3,INFINITE);//p(&s2) EnterCriticalSection(&x); cout<<\顾客C\< EnterCriticalSection(&coun); amount ++; LeaveCriticalSection(&coun); EnterCriticalSection(&x); cout<<\该顾客在门外等待,已有\< 财服务\< } Sleep(ServeTime); m3--; ReleaseSemaphore(seat,1,NULL);//v(&seat) EnterCriticalSection(&c_seat); seat_num++; LeaveCriticalSection(&c_seat); if(seat_num<=0) { } EnterCriticalSection(&x); cout<<\顾客C\< EnterCriticalSection(&x); cout<<\门外还剩\< int main(void)//主程序 {//创建信号量和线程 cout<<\顾客您好,欢迎来到我行,很高兴为您服务!\< for(n=0;n ss1[n]=CreateThread(NULL,0,server1,NULL,0,NULL); ss2[n]=CreateThread(NULL,0,server2,NULL,0,NULL); ss3[n]=CreateThread(NULL,0,server3,NULL,0,NULL); for(n=0;n for(;number int m=rand()%Customer_time; Sleep(m); int i=rand()@0; if(i>1&&i<=240) { } //用随机数来判断顾客是对私还是对公还是理财 c1[n]=CreateThread(NULL,0,consumer1,NULL,0,NULL); n++; else if(i>240&&i<=320) } } Sleep(80); EnterCriticalSection(&x); cout<<\循环再这里结束,不再创建新线程\< cout<<\已服务\< { } else { } c3[n2]=CreateThread(NULL,0,consumer3,NULL,0,NULL); n2++; c2[n1]=CreateThread(NULL,0,consumer2,NULL,0,NULL); n1++;
正在阅读:
操作系统课程设计报告lxx10-14
java课程设计报告04-11
java课程设计报告模板04-21
第二讲数控机床进给系统设计_之二_05-31
高中军训日记850字10-29
2018年贵州省黔西南州中考化学试卷04-19
高考一轮复习必备—圆锥曲线讲义01-11
牛津小学英语单词带音标分类08-09
2018-2024年中国水状农药制剂市场研究报告(目录) - 图文10-20
如何做好江城县的粮食安全生产工作11-11
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 操作系统
- 课程
- 报告
- 设计
- lxx
- 妇产科护理学本科练习题B
- 高考英语一轮复习人教版必修三 Unit 5 Canada-The True North名师精编单元测试
- 某温泉度假村经营方案
- 机关事业单位通用网址注册申请表
- 综合实践海豚小档案教学设计
- 审证练习1
- 2014下半年安徽教师资格证考试题目丨考试题库丨考试资料46
- 会计从业资格《财经法规》复习资料
- 注会考试《审计》知识点(4)
- 100天超人养成计划
- 认知语言学讲稿
- 寒假自主学习计划书
- 2011.9计算机等级考试四级网络工程师笔试试题(附答案) - 图文
- 法律英语(段落翻译与作文)
- 第八章、知识的建构和表征
- 关于市残疾人需求分析调研报告
- 专职人武部干部
- 2017年“中秋、国庆”期间建设工程安全生产和文明施工大检查通知
- 看守所简报2016年5月
- 05 思维与想象(信阳师范学院教育心理学试题库)