可以理解为代理商是分配资源的操作系统,吸烟者是需要资源的应用程序,要确保:如果资源可用,允许再多执行一个应用程序;相反如果应用程序无法继续,需要避免唤醒它。另外,需要添加限制,不能修改代理代码,如果代理表示操作系统,不希望每次新应用程序出现时都修改代理。
信号量:
agentSem = Semaphore(1)
tobacco = Semaphore(0)
paper = Semaphore(0)
match = Semaphore(0)
代理商需要三个并发线程,分别代表提供其最终的两种配料。
Agent A: //提供烟草和纸的代理商
while true:
P(agentSem)
V(tobacco)
V(paper)
Agent B: //提供纸和火柴的代理商
while true:
P(agentSem)
V(paper)
V(match)
Agent C: //提供火柴和烟草的代理商
while true:
P(agentSem)
V(match)
V(tobacco)
需要引入三个Pusher的辅助线程和附加变量和信号量,比如isTobacco表示烟草是否已经供应,tobaccoSem实现Pusher和Smokers with tobacco的同步,也就是去唤醒只有tobacco的吸烟者,其他同理。
isTobacco = isPaper = isMatch = False
tobaccoSem = Semaphore(0)
paperSem = Semaphore(0)
matchSem = Semaphore(0)
Pusher A:
while true:
P(tobacco)
P(mutex)
if isPaper:
isPaper = False
V(matchSem)
elif isMatch:
isMatch = Flase
V(paperSem)
else:
isTobacco = True
V(mutex)
Pusher B:
while true:
P(paper)
P(mutex)
if isTobacco:
isTobacco = False
V(matchSem)
elif isMatch:
isMatch = Fales
V(tobaccoSem)
else:
isPaper = True
V(mutex)
Pusher C:
while true:
P(match)
P(mutex)
if isTobacco:
isTobacco = False
V(paperSem)
elif isPaper:
isPaper = False
V(tobaccoSem)
else:
isMatch = true
V(mutex)
Smoker with tobacco:
while true:
P(tobaccoSem)
makeCigarette()
V(agentSem)
smoke()
Smoker with paper:
while true:
P(paperSem)
makeCigarette()
V(agentSem)
smoke()
Smoker with match:
while true:
P(smokeSem)
makeCigarette()
V(agentSem)
smoke()
如果代理商不等待吸烟者,则需要用整数来计算桌子上烟草、纸和火柴的数量。
numTobacco = numPaper = numMatch = 0
Pusher A:
while true:
P(tobacco)
P(mutex)
if numPaper > 0:
numPaper -= 1
V(matchSem)
elif numMatch > 0:
numMatch -= 1
V(paperSem)
else:
numTobacco += 1
V(mutex)
理发师等待customer信号,直到顾客进入理发店,然后顾客等待barber信号,直到理发师发出信号让他坐下来。理发后,顾客发出customerDone信号,并等待理发师的barberDone信号。
int customer = 0;
semaphore mutex = 1; //互斥访问customer
semaphore customer = 0;
semaphore barber = 0;
semaphore customerDone = 0;
semaphore barberDone = 0;
Process Barber
while (true) {
P(customer);
V(barber);
curHair();
P(customerDone);
V(barberDone);
}
Process Customer
P(mutex);
if (customers == n + 1) {
V(mutex);
} else {
customers += 1;
V(mutex);
V(customer);
P(barber);
getHairCut();
V(customerDone);
P(barberDone);
P(mutex);
customers -= 1;
V(mutex);
}
self
,如果编写self.sem = Semaphore(0)
,则每个线程都会获得自己的信号量customers = 0
mutex = Semaphore(1)
customer = Semaphore(0)
customerDone = Semaphore(0)
barberDone = Semaphore(0)
queue = []
Process Customer
self.sem = Semaphore(0)
P(mutex)
if customers == n + 1:
V(mutex)
else:
customer += 1
queue.append(self.sem)
V(mutex)
V(customer)
P(self.sem)
getHairCut()
V(customerDone)
P(barberDone)
P(mutex)
customers -= 1
V(mutex)
Process Barber
P(customer)
P(mutex)
sem = queue.pop(0)
V(mutex)
cutHair()
P(customerDone)
V(barberDone)
附加规范:
elves = 0
reindeer = 0
santaSem = Semaphore(0)
reindeerSem = Semaphore(0)
elfTex = Semaphore(1) //防止额外的精灵进入
mutex = Semaphore(1) //互斥访问elves和reindeer
Process Reindeer
P(mutex)
reindeer += 1
if reindeer == 9:
V(santaSem)
V(mutex)
P(reindeerSem)
getHitched()
Process elfTex
//前两个精灵在释放互斥锁的同时释放elfTex,但最后一个精灵拥有elfTex,禁止其他精灵进入,直到所有三个精灵都调用了getHelp。最后一个离开的精灵释放elfTex,允许下一批精灵进入
P(elfTex)
P(mutex)
elves += 1
if elves == 3:
V(santaSem)
else:
V(elfTex)
V(mutex)
getHelp()
P(mutex)
elves -= 1
if elves == 0:
V(elfTex)
V(mutex)
Process Santa
P(santaSem)
P(mutex)
if reindeer >= 9:
prepareSleigh()
for i in range(9):
V(reindeerSem)
reindeer -= 9
elif elves == 3:
helpElves()
V(mutex)
该题是H20问题的变形。以下只给出了黑客线程,员工线程对称。
barrier = Barrier(4)
mutex = Semaphore(1)
hackers = 0
serfs = 0
hackerQueue = Semaphore(0)
serfQueue = Semaphore(0)
local isCaptain = False //local是局部变量,使最后一个登船的线程调用rowBoat
Process Hacker
P(mutex)
hackers += 1
if hackers == 4:
V(hackerQueue)
V(hackerQueue)
V(hackerQueue)
V(hackerQueue)
hackers -= 4
isCaptain = True
elif hackers == 2 and serfs >= 2:
V(hackerQueue)
V(hackerQueue)
V(serfQueue)
V(serfQueue)
serfs -= 2
hackers -= 2
isCaptain = True
else:
V(mutex)
P(hackerQueue)
board()
barrier.wait()
if isCaptain:
rowBoat();
V(mutex)
分析题目只有一种情况需要等待:一个学生正在吃饭,另一个学生准备离开。要解决这种现象,有两种方法:(1)等另外一个学生来吃饭;(2)等正在吃饭的同学一起吃完离开。
eating = 0
readyToLeave = 0
mutex = Semaphore(1)
okToLeave = Semaphore(0)
getFood()
P(mutex)
eating += 1
if eating == 2 and readyToLeave == 1:
V(okToLeave)
readyToLeave -= 1
V(mutex)
dine()
P(mutex)
eating -= 1
readyToLeave += 1
if eating == 1 and readyToLeave == 1:
V(mutex)
P(okToLeave)
elif eating == 0 and readyToLeave == 2:
V(okToLeave)
readyToLeave -= 2
V(mutex)
else:
readyToLeave -= 1
V(mutex)
leave()
题目来自https://blog.csdn.net/booksyhay/article/details/82692362