|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
引入服务生解法之后只有偶数项的进程能够拿到两个叉子
有办法能让奇数进程也能拿到叉子吗
- # -*- coding:utf-8 -*-
- import threading
- from time import sleep
- numPhilosophers = numForks = 10
- class Philosopher(threading.Thread):
- def __init__(self, index):
- threading.Thread.__init__(self)
- self.index = index
- self.leftFork = forks[self.index]
- self.rightFork = forks[(self.index + 1) % numForks]
- def run(self):
- while True:
- if waiter.serve(self):
- self.dining()
- waiter.clean(self)
- self.thinking()
- def dining(self):
- print ("Philosopher", self.index, " starts to eat.")
- sleep(1/1000)
- print ("Philosopher", self.index, " finishes eating and leaves to think.")
- def thinking(self):
- sleep(1/100)
- class Fork():
- def __init__(self, index):
- self.index = index
- self._lock = threading.Lock()
- def pickup(self):
- self._lock.acquire() #申请锁定进程
- def putdown(self):
- self._lock.release() #释放进程
- class Waiter:
- def __init__(self):
- self.forks = [Fork(idx) for idx in range(numForks)]
- #最开始餐叉还没有被分配给任何人,所以全部 False
- self.forks_using = [False] * numForks
- #如果哲学家的左右餐叉都是空闲状态,就为这位哲学家服务提供餐叉
- def serve(self, philor):
- if not self.forks_using[philor.leftFork.index] and not self.forks_using[philor.rightFork.index]:
- self.forks_using[philor.leftFork.index] = True
- self.forks_using[philor.rightFork.index] = True
- self.forks[philor.leftFork.index].pickup()
- self.forks[philor.rightFork.index].pickup()
- return True
- else:
- return False
- #哲学家用餐完毕后,清理并回收餐叉
- def clean(self, philor):
- self.forks[philor.leftFork.index].putdown()
- self.forks[philor.rightFork.index].putdown()
- self.forks_using[philor.leftFork.index] = False
- self.forks_using[philor.rightFork.index] = False
- if __name__ == '__main__':
- #创建服务生与哲学家实例
- waiter = Waiter()
- forks = [Fork(idx) for idx in range(numForks)]
- philosophers = [Philosopher(idx) for idx in range(numPhilosophers)]
- #开启所有的哲学家线程
- for philosopher in philosophers:
- philosopher.start()
- # 方便 CTRL + C 退出程序
- try:
- while True: sleep(0.1)
- except Exception:
- raise e
复制代码 |
|