【问题标题】:How to solve the Sleeping Barbers analogy with multiple barbers in Python?如何在 Python 中解决与多个理发师的睡眠理发师类比问题?
【发布时间】:2018-04-17 20:10:51
【问题描述】:

我有一个解决睡眠理发师操作系统问题的工作解决方案,它使用 python 2.7 和线程,适用于单个理发师和一定数量的椅子。但我希望它能够在有多个理发师的情况下工作,就像有多个客户一样。

这是我目前使用一个理发师的解决方案:

from threading import Thread, Lock, Event
import time, random
from sys import exit
lock = Lock()
customerIntervalMin = 5
customerIntervalMax = 15
haircutDurationMin = 3
haircutDurationMax = 15

class BarberShop:
        waitingCustomers = []
        threads=[]
        finishedCustomers = []

        def __init__(self, barber, numberOfSeats):
                self.barber = barber
                self.numberOfSeats = numberOfSeats

        def openShop(self):
                print 'Barber shop is opening'
                workingThread = Thread(target = self.barberGoToWork)
                workingThread.start()
                self.threads.append(workingThread)


        def barberGoToWork(self):
                while True:
                        lock.acquire()

                        if len(self.waitingCustomers) > 0 and len(self.finishedCustomers)< 5:
                                c = self.waitingCustomers[0]
                                del self.waitingCustomers[0]
                                lock.release()
                                self.barber.cutHair(c)
                                self.finishedCustomers.append(c)
                        elif  len(self.waitingCustomers)==0 and len(self.finishedCustomers)<5:
                                lock.release()
                                print 'Aaah, all done, {0} is going to sleep'.format(barber.name)
                                barber.sleeps()
                                print '{0} woke up'.format(barber.name)
                        elif len(self.waitingCustomers)==0 and len(self.finishedCustomers)==5:
                                lock.release()
                                print 'The barber shop is closed. Come back tomorrow.'
                                exit(0)


        def enterBarberShop(self, customer):
                lock.acquire()
                print '{0} entered the shop and is looking for a seat'.format(customer.name)

                if len(self.waitingCustomers) == self.numberOfSeats:
                        print 'Waiting room is full, {0} is leaving.'.format(customer.name)
                        lock.release()
                else:
                        print '{0} sat down in the waiting room'.format(customer.name)
                        self.waitingCustomers.append(c)
                        lock.release()
                        barber.wakeUp()

class Customer:
        def __init__(self, name):
                self.name = name

class Barber:
        def __init__(self, name):
                self.name = name

        barberEvent = Event()

        def sleeps(self):
                self.barberEvent.wait()

        def wakeUp(self):
                self.barberEvent.set()

        def cutHair(self, customer):
                self.barberEvent.clear()
                print '{0} is having a haircut done by {1}'.format(customer.name, self.name)
                randomHairCuttingTime = random.randrange(haircutDurationMin, haircutDurationMax+1)
                time.sleep(randomHairCuttingTime)
                print '{0} is done with {1}'.format(customer.name, self.name)


if __name__ == '__main__':
        customers = []
        customers.append(Customer('Ken'))
        customers.append(Customer('Scott'))
        customers.append(Customer('Larry'))
        customers.append(Customer('Liam'))
        customers.append(Customer('Kieran'))

        barber = Barber('Mark')
        barberShop = BarberShop(barber, numberOfSeats=10)
        barberShop.openShop()

        while len(customers) > 0:
                c = customers.pop()
                barberShop.enterBarberShop(c)
                customerInterval = random.randrange(customerIntervalMin,customerIntervalMax+1)
                time.sleep(customerInterval)

我很困惑如何解决这个问题。我最初认为它与 main 中的客户列表相同,您只需将类和给定名称参数附加到列表中,使用循环遍历列表,弹出列表中的每个实例并将其分配给barber & 主要保留原始的barberShop 定义。但经过反思,这是不对的,因为这只会创建 3 个不同的线程,每个线程有 10 个座位。所以现在我不确定如何解决这个问题的最后一部分,虽然在 Java 和 C 等语言中有很多关于这个问题的特定方面的在线实现,但我对这些语言没有足够的经验来理解这些解决方案,更不用说将它们翻译成python并在上面的解决方案中实现它的各个方面。

有没有其他方法可以在这个解决方案中实现多个理发师?对于问题的这方面的任何帮助或任何可以对我的解决方案进行改进的建议将不胜感激。

【问题讨论】:

  • 欢迎来到 StackOverflow。请按照您创建此帐户时的建议阅读并遵循帮助文档中的发布指南。 On topichow to ask 在这里申请。 StackOverflow 不是设计、编码、研究或教程服务。一般来说,您应该对如何解决问题、实现该想法的一些代码以及该代码的特定问题有一个集中的想法。

标签: python multithreading python-2.7 process python-multithreading


【解决方案1】:

您需要完全按照您在文字中描述的方式设计您的系统:您实例化三个理发师,每个理发师都拥有相同十张椅子的等候室的完全权限。这意味着您的互斥操作必须足够强大,可以容纳 3 个参与者和 10 个目标。您还必须让新客户叫醒熟睡的理发师,无论有多少人睡着了。

考虑您的理发师状态和客户状态。依次关注每个组合,并设计系统应如何反应。然后,根据这些不同的操作(例如“客户叫醒理发师”、“理发师将客户移到工作椅上”),决定如何将您的方法分配给类。

这对你有帮助吗?

【讨论】:

  • 这很有帮助。您能否详细说明一下互斥操作对于 3 个演员和 10 个目标来说足够强大是什么意思?我之前测试过代码,椅子的数量大于和小于 10 以及多个客户,我对它的运行方式感到满意,但我只是不确定如何实际定义理发师。关于实例化理发师,您有什么特别要给我的建议吗?您是否同意我之前以与客户类似的方式定义它们的想法是一种糟糕的做法?
  • 您要求获得有关系统设计的个人教程;这在两个方面超出了声明的 Stack Overflow 目的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-17
  • 1970-01-01
  • 2020-02-27
相关资源
最近更新 更多