最后交稿课程设计.docx

上传人:b****5 文档编号:12379427 上传时间:2023-04-18 格式:DOCX 页数:12 大小:51.85KB
下载 相关 举报
最后交稿课程设计.docx_第1页
第1页 / 共12页
最后交稿课程设计.docx_第2页
第2页 / 共12页
最后交稿课程设计.docx_第3页
第3页 / 共12页
最后交稿课程设计.docx_第4页
第4页 / 共12页
最后交稿课程设计.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

最后交稿课程设计.docx

《最后交稿课程设计.docx》由会员分享,可在线阅读,更多相关《最后交稿课程设计.docx(12页珍藏版)》请在冰豆网上搜索。

最后交稿课程设计.docx

最后交稿课程设计

网络操作系统课程设计

 

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拷到工程目录下,然后再加进工程就可以了

九、运行结果

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 电力水利

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1