理发师问题
问题描述:理发店里有一位喜欢睡觉的理发师、一把理发椅和n个等待位。若没有顾客,理发师便在理发椅上睡觉,当有顾客到来时,他就被顾客唤醒并为其服务。如果理发师正在为顾客理发时有新顾客到来,且有空的等待位,顾客就坐下来等候;若无空位子,顾客就离开。
环境:Windows环境下利用python语言实现理发师问题。软件pycharm或python3.7或3.8
理发师问题用P,V操作叙述如下:
int waiting=0;
//顾客数量(理发+等待的,最多n+1人)
semaphore mutex=1;
//waiting的互斥操作权
semaphore bchair=1;
//理发椅互斥信号量
semaphore wchair=n;
//等待位资源信号量
Semaphore ready=finish=0;
//理发师与顾客间通信的同步信号量
barber() //理发师进程
{
while(true)
{
/*查看是否 有顾客需要理发,若有就为其理发,否则就睡觉*/
P(ready);
理发;
V(finish); //完成理发,提醒顾客离开,同时通知下一位顾客:到我碗里来!
}
}
customer() //顾客进程
{
P(mutex); //申请互斥的修改waiting变量的值
if (waiting <=n ) //若还有空位(包括等待位和理发椅),留下
{
waiting++;
V(mutex); //释放对waiting的互斥控制
}
else
{
V(mutex);
没空位,走人;
}
P(wchair); //找等待位坐下
P(bchair); //等待理发椅空闲
V(wchair); //一坐上理发椅就立即释放等待位
V(ready); //理发师,我跳碗里了
P(finish); //等待理发完成
V(bchair); //照照镜子,完美!释放理发椅
P(mutex); //修改waiting值
waiting--;
V(mutex)
}
main()
{
cobegin //理发师进程与顾客进程并发执行
barber();
customer();
coend
}
实际代码实现:
import threading
import time
import random
ready= threading.Semaphore(0)#定义一个理发开始传递信号量
finish = threading.Semaphore(0)#定义理发结束的信号量
mutex = threading.Lock()#互斥锁设置
wait_customer = 0#初始理发人数
wchair=threading.Lock()#等待椅子是互斥的
barchair=threading.Lock()#理发椅是互斥的
CHAIRS = 6#椅子的个数
#CHAIRS = random.randint(0,10)#椅子的个数
couter=0#编号
def customer():#顾客进程设计
#变量引用声明
global wait_customer
global CHAIRS
global mutex
global wchair,finish,barchair,ready
global couter
time.sleep(2)
mutex.acquire()#进入临界区,修改等待人数
if (wait_customer <= CHAIRS):
wait_customer += 1
couter += 1
print('''顾客的当前人数为:''' , wait_customer)
mutex.release()
# barbers.acquire()
else:
couter += 1
print('人数已满,已经没有座位,编号为:{}离开'.format(couter))
mutex.release()
wchair.acquire()#等待椅子资源是否可用
barchair.acquire()#等待理发
wchair.release()#可以理发,释放等待椅子资源
ready.release()#向理发师发送信号
finish.acquire()#等待理发完毕
barchair.release()#释放理发椅资源
mutex.acquire()#修改顾客人数
wait_customer -= 1
mutex.release()
def barber():
#理发师进程
print('理发师进程:',end='')
global wait_customer
global CHAIRS
global mutex
global ready,finish
while (1):
if (wait_customer == 0):
print('没有顾客,睡觉')
time.sleep(1)
ready.acquire()#等待顾客发出请求
cut_hair()
finish.release()#理发完毕
def cut_hair():
print('我正在理发。')
time.sleep(2)
print('理发完毕!')
if __name__ == "__main__":
t1 = threading.Thread(target=barber)
t1.start()
t1.join(1)
while (1):
try:
time.sleep(0.5)
t2 = threading.Thread(target=customer)
t2.start()
t2.join(1)
except Exception:
print("出错了")
运行截图: