理发师问题的实现说明书
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
打瞌睡的理发师
理发师问题是一个利用信号量进行PV操作的经典问题。设计程序实现此问题,要使得理发师的活动与顾客的活动得到各自真实的模拟。所执行的程序应体现:理发师在没有顾客的时候去睡觉,有顾客则工作;顾客在理发师工作时坐下等待,无座时离开,直至等到理发师自己理发。
打瞌睡的理发师问题是一种同步问题的抽象描述。计算机系统中的每个进程都可以消费或生产某类资源,当系统中某一进程使用某一资源时,可以看作是消耗,且该进程称为消费者。而当某个进程释放资源时,则它就相当一个生产者。因此此题可看作是n个生产者和1个消费者问题。顾客作为生产者,每到来一个就使计数器count增加1,以便让理发师理发(相当于消费)至最后一个顾客(相当于产品)。并且,第1个到来的顾客应负责唤醒理发师;如果不是第1个到达的顾客,则在有空椅子的情况下坐下等待,否则离开理发店(该消息可由计数器count获得)。所以可以通过一个有界缓冲区把理发师和顾客联系起来。而其中的信号也具有两种功能:一是跟踪资源的理发师和顾客的计数器;二是协调资源的理发师和顾客之间的同步器。通过
对信号进行P、V操作来实现有关问题和相关描述。
一、数据结构:
1、信号量:
int Custom;//所有到达的顾客,包括正在被理发的顾客,所以一般情况下,Custom比Wait_Person大1
int Mutex;//用于实现全局变量Wait——preson访问的互斥
int Wait_Leave;//等待离开信号量,用来表示几个顾客等待离开,只要理发师为其理发完毕,他就可以离开了
2、全局变量:
int * Is_Sleeping;//当前理发师是否在睡觉
3、函数:
void print1(int Wait_person)
void print2(int ID)
4:Linux 提供的多线程函数:
int pthread_create(pthread_t *—thread,_const pthread_attr_t
*attr,void* (*start_rtn)(void*),void *arg);
int pthread_join __P ((pthread_t __th, void
**__thread_return));pthread_attr_init(&attr);
pthread_attr_getschedparam(&attr, ¶m);
param.sched_priority=newprio;
pthread_attr_setschedparam(&attr, ¶m);
pthread_create(&tid, &attr, (void *)myfunction, myarg);
pthread_detach(thread_id);pthread_t pthread_self(void);
二、程序模块:
1、理发师模块流程图:
开始
初始化变量
True
wait(customers)
wait(mutex)
count--
signal(mutex)
cut_hair
signal(barber) 2、顾客模块流程图:
开始
初始化变量
True
wait(mutex)
count++
signal(mutex)
get_haircut
wait(barber)
count signal(customers) signal(mutex) false true 3、主程序流程图: 开始 创建并初始化信号量 0!=ret 创建理发师线程 创建顾客线程 等待理发师线程结束 等待顾客线程结束 信号量初始化失败 0!=ret 理发师线程失败 i<10 0!=ret 顾客线程失败 i<10 结束 true false true true false false false true true false 4、PV操作伪代码 int waiting=0 ; //等候理发的顾客数 int chairs=n; //为顾客准备的椅子数 semaphore customers=0, barbers=0,mutex=1; barber() { while(TRUE); //理完一人,还有顾客吗? P(cutomers); //若无顾客,理发师睡眠 P(mutex); //进程互斥 waiting -= 1;//等候顾客数少一个 V(barbers); //理发师去为一个顾客理发 V(mutex); //开放临界区 cut-hair( ); //正在理发 } customer() { P(mutex); //进程互斥 if (waiting) { waiting += 1; // 等候顾客数加1 V(customers); //必要的话唤醒理发师 V(mutex); //开放临界区 P(barbers); //无理发师, 顾客坐着养神 get-haircut( ); //一个顾客坐下等理/ } else V(mutex); //人满了,离开 } 三、测试结果: 1、代码编辑: