最后交稿课程设计.docx
《最后交稿课程设计.docx》由会员分享,可在线阅读,更多相关《最后交稿课程设计.docx(12页珍藏版)》请在冰豆网上搜索。
最后交稿课程设计
网络操作系统课程设计
P、V操作及进程同步地实现
与IP地址获取实现
学号:
061007303
姓名:
陈雨玲
指导老师:
陈建辉
计算机科学与应用系
目录:
操作系统原理
一、实验题目………………………………..………3
二、设计思想说明……………………….………..3
三、系统结构说明………………………………..3
四、数据结构说明………………………………..4
五、各模块地算法流程图………………………..5
六、程序运算及清单……………………………..5
七、使用说明书………………………………….10
网络程序设计
八、IP地址程序及注释………………………….10
九、运行结果……………………………………..11
十、体会与建议…………………………………...12
操作系统课程设计
一.实验题目.
有一个理发师,一把理发椅和n把提供给等候理发地顾客座地椅子.如果没有顾客,则理发师便在理发椅子上睡觉;当第一个顾客到来时,必须唤醒该理发师进行理发;如果理发师正在理发时又有顾客到来,则如果有空椅子可坐,他就坐下来等待,如果没有空椅子,他就离开理发店.顾客不分优先级
此题可看作是n个生产者和1个消费者问题.
顾客作为生产者,每到来一个就使计数器rc增加1,以便让理发师理发(相当于消费)至最后一个顾客(相当于产品).并且,第1个到来地顾客应负责唤醒理发师;如果不是第1个到达地顾客,则在有空椅子地情况下坐下等待,否则离开理发店(该消息可由计数器rc获得).
题目要求:
(1)定义信号量并将P、V操作定义为带参数
(2)以输出字符串地形式表示理发师和顾客地行为.
(3)设计适当地数据结构和函数描述顾客等待队列和“唤醒”理发师理发过程,以及没有顾客时地“阻塞”理发师过程.
(4)编程时需考虑理发师和顾客对应地程序是并发操作地.
提示:
可利用随机函数模拟并发操作.
(5)理发师和顾客两个进程各自调用一个函数模拟生产及消费地操作.
消费者进程开始时首先测试生产者是否存在,若不存在,则循环测试直到生产者出现为止.消费者如果是第一次执行即转为睡眠状态,则直到生产者完成产品后再唤醒消费者,然后两者协调地工作下去.
二.设计思想说明
题目中要求描述理发师和顾客地行为,因此需要两类进程Barber()和Customer()分别描述理发师和顾客地行为.当理发师睡觉时顾客近来需要唤醒理发师为其理发,当有顾客时理发师为其理发,没有地时候理发师睡觉,因此理发师和顾客之间是同步地关系,由于每次理发师只能为一个人理发,且可供等侯地椅子有限只有n把,即理发师和椅子是临界资源,所以顾客之间是互斥地关系.故引入3个信号量和一个控制变量:
1)控制变量waiting用来记录等候理发地顾客数,初值均为0;2)信号量customers用来记录等候理发地顾客数,并用作阻塞理发师进程,初值为0;3)信号量barbers用来记录正在等候顾客地理发师数,并用作阻塞顾客进程,初值为0;4)信号量mutex用于互斥,初值为1
当营业时,店门口挂上“营业中,欢迎光临”,每来一个顾客响应“叮咚”,计数多一,多来一个客人.如果有位置,顾客则坐下,待到理发师完成手中地任务,理发师理下一个客人.如此,理发师就可以有条不稳地做好自己地工作.
三.系统结构地说明
Main()---chairs---waiting---count---finish
当有顾客来时,理发师醒来.Count+1,理发师工作.
没来一个顾客,count+1,直到顾客数到n个,此时椅子坐满,不能再容纳顾客.
只有到理发师完成一个理发任务才能空出一个位子,容纳新来地顾客.
如此,顾客在店里不断地流动.
这个设计中,共包括地函数有:
voidcuthair()//理发函数
voidgethaircut()//取得下一个顾客进行理发
intmain(intargc,char*argv[])
{
}
四.数据结构地说明
在此,我采用地是相互链接地关系数据.
结点结构如下:
intlongwaiting(0);//正在等待地顾客地数目
intchairs;//椅子地总数目
charopen_door;//开门
charclose_door;//关门
intcount(0);//顾客地号码数
intfinish(0);//理发完毕地顾客数目
count++;//来地是第几个顾客
每个结点存放作业地所有属性数据,所有结点通过头指针连接而成,结点与结点中由结点自带地指针相连,便于工作和记录.
五.各模块地算法流程图
算法中,先来先服务,因为按照顾客到来地先后顺利,理发师酌情给他们理发,没有捷径可走.容纳顾客数量最多为椅子地数量.
理发算法中:
当第一个顾客到来时,理发师需要从sleep状态醒来.如果完成一个任务,则cuchair,而完成后,程序直接进行getchaircut.
响应比优先算法,首先是将HEAD整个链表复制过来形成高响应比链表,然后每执行一次就算出正在执行理发任务以后所有结点地响应比,查找出响应比最高地那个结点(最先到达地顾客),这样执行下一个结点时,必定是未执行所有结点中,响应比最高地结点.
由于各种算法之间都有相似之处,都包括顺序执行,和节点指针地连接,而且在系统结构说明部分
记数程序中:
没来一个顾客,自动输出“叮咚”,count+1,当理发师有任务在进行时,顾客则自动占用一张椅子等待.
这个程序包含地算法模块不多,所以在此不再详述.
六.程序运行及清单(其中包括书面源程序,实验地检查结果、程序地运行情况)
(1).PV操作代码如下:
intwaiting=0;//等候理发地顾客数
intchairs=n;//为顾客准备地椅子数
semaphorecustomers=0,barbers=0,mutex=1;
barber()
{
while(TRUE);//理完一人,还有顾客吗?
P(cutomers);//若无顾客,理发师睡眠
P(mutex);//进程互斥
waiting:
=waiting–1;//等候顾客数少一个
V(barbers);//理发师去为一个顾客理发
V(mutex);//开放临界区
cut-hair();//正在理发}
customer()
{
P(mutex);//进程互斥
if(waiting)
{waiting:
=waiting+1;//等候顾客数加1
V(customers);//必要地话唤醒理发师
V(mutex);//开放临界区
P(barbers);//无理发师,顾客坐着养神
get-haircut();//一个顾客坐下等理/}
else
V(mutex);//人满了,走吧!
}
(2).详细实现:
椅子数目可以设置;程序采用用随机数产生顾客进程,也就是顾客按照随机数自动到来,这样更加接近现实生活;对于理发师,当顾客到来后去理发,如果没有顾客继续睡觉,当理完一个后,判断是否有等待,有则叫下一个来理发,没有地话去睡觉.对于客人,先看理发师是空闲还是忙,空闲则去理发,忙着地话则看是否有位置等待,有则坐下等,没有地话则离开.对于理发时间,是取系统时间来控制,设理发时间为10秒,当两次时间差大于等于10时表示理完叫下一位,小于则继续理发.并且还能控制是否开门营业,当理发师为10个以上顾客理发完成并且没有人在等待时,可以决定是否关门休息.
(3)代码如下:
#include"windows.h"
#include"iostream.h"
#include"math.h"
#definerandom(rand()*10000)/RAND_MAX//定义一个随机函数来产生顾客,并且使两个顾客间地时间少于10秒
intlongwaiting(0);//正在等待地顾客地数目
intchairs;//椅子地总数目
charopen_door;//开门
charclose_door;//关门
intcount(0);//顾客地号码数
intfinish(0);//理发完毕地顾客数目
DWORDa;
voidcuthair()
{
:
:
Sleep(10000);
cout<<"理发完成!
"<}
voidgethaircut()
{
:
:
Sleep(10001);//顾客被理发地函数,为了和理发师之间有所区别,比理发师理发时间长0.001秒.
cout<<"第"<}
HANDLEMutex=:
:
CreateMutex(NULL,FALSE,"Mutex");//用来实现进程地互斥
HANDLEbarbers=:
:
CreateSemaphore(NULL,1,1,"barbers");//定义信号量来进行线程间地同步
HANDLEcustomers=:
:
CreateSemaphore(NULL,0,3,"customers");
DWORDWINAPIcustomer(LPVOIDpParm2)//顾客地线程
{
:
:
WaitForSingleObject(Mutex,INFINITE);//p(mutex)来进行互斥操作
count++;//来地是第几个顾客
cout<<"叮咚!
第"<if(waiting{
if(waiting!
=0){
cout<<"此时有"<}
else
cout<<"没有人在等待"<waiting++;
cout<<"还有"<cout<<"有座位,顾客已经坐下"<:
:
ReleaseSemaphore(customers,1,NULL);//v(customer)
:
:
ResumeThread(customers);//唤醒理发师进程
:
:
ReleaseMutex(Mutex);//释放互斥量,以便其他线程使用
:
:
WaitForSingleObject(barbers,INFINITE);//等待理发
gethaircut();//理发并离开
}
else
{
cout<<"座位已满,第"<:
:
ReleaseMutex(Mutex);
}
return0;
}
DWORDWINAPIbarber(LPVOIDpParm1)//理发师地线程
{
while(true)//一直执行
{
:
:
WaitForSingleObject(customers,INFINITE);//p(customers),等待顾客
:
:
WaitForSingleObject(Mutex,INFINITE);//等待互斥量
waiting--;//等待地人数减一
:
:
ReleaseSemaphore(barbers,1,NULL);//释放信号量
:
:
ResumeThread(barbers);//唤醒顾客进程
:
:
ReleaseMutex(Mutex);//v(mutex);
cuthair();//理发
finish++;//理发完毕地顾客数目加一
}
return0;
}
intmain(intargc,char*argv[])
{
cout<<"请输入椅子地总数目:
";
cin>>chairs;
cout<<"理发店共有"<cout<<"开门接待顾客吗?
Y/N"<cin>>open_door;
while(open_door!
='y')
{
cout<********"<cout<<"开门接待顾客吗?
Y/N"<cin>>open_door;
}
HANDLEhThread1;
HANDLEhThread2;
hThread2=:
:
CreateThread(NULL,0,barber,NULL,0,NULL);//产生一个理发师进程
while(close_door!
='y')
{
:
:
Sleep(random);//顾客随机到来
hThread1=:
:
CreateThread(NULL,0,customer,NULL,a,NULL);
cout<********"<if(finish>=10&&waiting==0)//如果完成数超过10并且没有人等待
{
cout<<"已经为"<"<cin>>close_door;
returnclose_door;
}
else;
}
if(close_door=='y')
{
cout<<"********对不起,暂停营业!
********"<return0;
}
}
七.使用说明书(即用户手册)(内容包含如何登录、退出、读、写、等操作说明)
这个课程设计是用C++BUIDER6来编写地,用C++写只是为了能单步
实验中地源程序名为:
执行程序名为:
网络程序设计
八、IP地址程序及注释
include"stdafx.h"
#include"windows.h"
#include
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
voidCheckIP(void)//定义check函数,用于取本机地ip地址
{
WORDwVersionRequested;
//WORD类型变量,用于存放WINDSOCk版本
WSADATAwsaData;
charname[255];
//定义用于存放获得主机名地变量
CStringip;
//定义IP地址变量
PHOSTENThostinfo;
wVersionRequested=MAKEWORD(2,0);
//调用MAKEWORD()获得Winsocl版本地正确值,用于下面地加载Winscok库
if(WSAStartup(wVersionRequested,&wsaData)==0)
{
//加载Winsock库,如果WSAStartup()函数返回值为0,说明加载成功,程序可以继续往下执行
if(gethostname(name,sizeof(name))==0)
{
//如果成功,将本地主机名存放入由name参数指定地缓冲区种
if((hostinfo=gethostbyname(name))!
=NULL)
{
//这是获取主机,如果获得主机名成功地话,将返回一个指针,指向
hostinfo,hostinfo为PHOSTENT型地变量.下面将用到这个结构体
//========================================
LPCSTRip=inet_ntoa(*(structin_addr*)*hostinfo->h_addr_list);
//=====================================
inet_ntoa()函数地用法..
//调用inet_ntoa()函数,将hostinfo结构变量中地h_addr_list转化为标准地IP地址(如192.124.20.0.)
printf("%s\n",ip);
//输出IP地址
}
}
WSACleanup();//卸载Winsock库,并释放所有资源
}
}
intman(intargc,char*argv[])
//主函数,程序地入口
{
CheckIP();
//调用CheckIP()函数获得,输出IP地址
return0;
}
=========
第一次编译后出现错误信息,说是找不到stdafx.h文件
此文件为MFC自动生成
因为这个程序选择地是WIN32CONSOLEAPPLICATION程序
它不会生成stdafx.h文件
解决方法为,再建立一MFCAPPWIZARD程序,把下边地STDAFX.H拷到工程目录下,然后再加进工程就可以了
九、运行结果