理发师问题的实现说明书Word格式文档下载.docx
《理发师问题的实现说明书Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《理发师问题的实现说明书Word格式文档下载.docx(17页珍藏版)》请在冰点文库上搜索。
![理发师问题的实现说明书Word格式文档下载.docx](https://file1.bingdoc.com/fileroot1/2023-4/29/64d4e9a5-6c2e-46c6-aeb7-55429bbdf012/64d4e9a5-6c2e-46c6-aeb7-55429bbdf0121.gif)
关键字·
设计思想·
4
正文·
一、数据结构·
5
1、信号量·
2、全局变量·
3、函数·
二、程序模块·
6
1、理发师模块流程图·
2、顾客模块流程图·
7
3、主程序流程图·
8
4、PV操作伪代码·
9
三、运行结果·
10
1、代码编辑·
2、编译运行·
12
3、运行结果·
设计总结·
13参考文献·
14
致谢·
15
附录:
源代码·
16
摘要
理发师问题是一个利用信号量进行PV操作的经典问题。
设计程序实现此问题,要使得理发师的活动与顾客的活动得到各自真实的模拟。
所执行的程序应体现:
理发师在没有顾客的时候去睡觉,有顾客则工作;
顾客在理发师工作时坐下等待,无座时离开,直至等到理发师自己理发。
关键字:
理发师,顾客,PV操作。
设计思想
打瞌睡的理发师问题是一种同步问题的抽象描述。
计算机系统中的每个进程都可以消费或生产某类资源,当系统中某一进程使用某一资源时,可以看作是消耗,且该进程称为消费者。
而当某个进程释放资源时,则它就相当一个生产者。
因此此题可看作是n个生产者和1个消费者问题。
顾客作为生产者,每到来一个就使计数器count增加1,以便让理发师理发(相当于消费)至最后一个顾客(相当于产品)。
并且,第1个到来的顾客应负责唤醒理发师;
如果不是第1个到达的顾客,则在有空椅子的情况下坐下等待,否则离开理发店(该消息可由计数器count获得)。
所以可以通过一个有界缓冲区把理发师和顾客联系起来。
而其中的信号也具有两种功能:
一是跟踪资源的理发师和顾客的计数器;
二是协调资源的理发师和顾客之间的同步器。
通过对信号进行P、V操作来实现有关问题和相关描述。
1、数据结构:
1、信号量:
intCustom;
//所有到达的顾客,包括正在被理发的顾客,所以一般情况下,Custom比Wait_Person大1
intMutex;
//用于实现全局变量Wait——preson访问的互斥
intWait_Leave;
//等待离开信号量,用来表示几个顾客等待离开,只要理发师为其理发完毕,他就可以离开了
2、全局变量:
int*Is_Sleeping;
//当前理发师是否在睡觉
3、函数:
voidprint1(intWait_person)
voidprint2(intID)
4:
Linux提供的多线程函数:
intpthread_create(pthread_t*—thread,_constpthread_attr_t*attr,void*(*start_rtn)(void*),void*arg);
intpthread_join__P((pthread_t__th,void**__thread_return));
pthread_attr_init(&
attr);
pthread_attr_getschedparam(&
attr,&
param);
param.sched_priority=newprio;
pthread_attr_setschedparam(&
pthread_create(&
tid,&
attr,(void*)myfunction,myarg);
pthread_detach(thread_id);
pthread_tpthread_self(void);
二、程序模块:
1、理发师模块流程图:
2、顾客模块流程图:
3、主程序流程图:
4、PV操作伪代码
intwaiting=0;
//等候理发的顾客数
intchairs=n;
//为顾客准备的椅子数
semaphorecustomers=0,barbers=0,mutex=1;
barber()
{
while(TRUE);
//理完一人,还有顾客吗?
P(cutomers);
//若无顾客,理发师睡眠
P(mutex);
//进程互斥
waiting-=1;
//等候顾客数少一个
V(barbers);
//理发师去为一个顾客理发
V(mutex);
//开放临界区
cut-hair();
//正在理发
}
customer()
if(waiting)
{
waiting+=1;
//等候顾客数加1
V(customers);
//必要的话唤醒理发师
V(mutex);
P(barbers);
//无理发师,顾客坐着养神
get-haircut();
//一个顾客坐下等理/
}
elseV(mutex);
//人满了,离开
}
三、测试结果:
1、代码编辑:
2、编译运行:
3、运行结果:
设计总结
本次课程设计完成了多进程同步方法理发师问题全部过程,结果满足设计要求,验证无误。
设计过程中也遇到不少困难,尤其是关于多进程程序的设计实现。
特别需要注意的是由于进程的数据共享会带来其他一些问题,while循环中的各个循环小模块需要严格区别开来,才能使输出结果正确有序。
这些正是编写多进程程序时最需要注意的地方。
通过本次设计,我较好地掌握了通过研究Linux的进程机制和信号量实现PV操作的全过程,尤其是对多进程程序设计方法有了更深的理解,开拓了思路,锻炼了实践动手能手,达到了课程设计目的。
参考文献
1.汤子瀛,哲凤屏.《计算机操作系统》.西安电子科技大学学出版社.
2.王清,李光明.《计算机操作系统》.冶金工业出版社.
3.孙钟秀等.操作系统教程.高等教育出版社
4.曾明.
Linux操作系统应用教程.陕西科学技术出版社.
5.张丽芬,刘利雄.《操作系统实验教程》.清华大学出版社.
6.孟静,
操作系统教程--原理和实例分析.高等教育出版社
7.周长林,计算机操作系统教程.高等教育出版社
8.张尧学,计算机操作系统教程,清华大学出版社
9.任满杰,操作系统原理实用教程,电子工业出版社
致谢
在此次课程设计的过程中,我首先要感谢我的指导老师王燕老师,给了我很大的帮助,与此同时班里的同学也教会了我很多相关Linux系统的许多知识,对此次课程设计的程序的调试工作给予了大力的帮助,通过这次课程设计,我学会了Linux系统下编程,调试以及运行C语言程序,同时更深刻地了解了操作系统的相关同步问题原理,使我学到了操作系统的更多知识。
源代码
#include<
sys/mman.h>
sys/types.h>
linux/sem.h>
fcntl.h>
unistd.h>
stdio.h>
errno.h>
time.h>
#defineN5
#defineM20
intMutex;
voidprint1(intWait_person)
{
if(!
Wait_person)
printf("
Nocustomerhere,gotosleep.\n"
);
*Is_Sleeping=1;
}
{
if(*Is_Sleeping)
Newcustomer%dcomes,weakupthebarber.\n"
ID);
*Is_Sleeping=0;
else
Newcustomer%dcomes,therearesomeschairsfree,sitsandwaites.\n"
intmain()
structsembufP,V;
unionsemunarg;
intPid,i=0;
int*Wait_Person;
//映射共享内存,临界区
Wait_Person=(int*)mmap(NULL,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
*Wait_Person=0;
Is_Sleeping=(int*)mmap(NULL,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
Custom=semget(IPC_PRIVATE,1,IPC_CREAT|00666);
Mutex=semget(IPC_PRIVATE,1,IPC_CREAT|00666);
Wait_Leave=semget(IPC_PRIVATE,1,IPC_CREAT|00666);
arg.val=0;
if(semctl(Custom,0,SETVAL,arg)==-1)
perror("
semctlsemevalerror"
arg.val=1;
if(semctl(Mutex,0,SETVAL,arg)==-1)
if(semctl(Wait_Leave,0,SETVAL,arg)==-1)
V.sem_num=0;
V.sem_op=1;
V.sem_flg=SEM_UNDO;
P.sem_num=0;
P.sem_op=-1;
P.sem_flg=SEM_UNDO;
Pid=fork();
if(Pid==0)
{//理发师进程
while
(1)
semop(Mutex,&
P,1);
print1(*Wait_Person);
V,1);
semop(Custom,&
(*Wait_Person)--;
Barberisworking!
\n"
sleep(3);
Onejobfinished.\n"
semop(Wait_Leave,&
******************Lastoneisfinished,closethedodr.**********************\n"
if((*Wait_Person)>
=N)
Newcustomer%dcomes,thereisnochairandgoaway.\n"
getpid());
exit(0);
print2(getpid());
唤醒理发师,否则,等待
(*Wait_Person)++;
Customer%dfinished,getoutofhere.\n"
sleep(rand()%100/30.0);
if(i<
M)
i++;
break;
if(i==M)
wait(NULL);
return0;