Python实现哲学家就餐问题实例代码


Posted in Python onNovember 09, 2020

哲学家就餐问题:

哲学家就餐问题是典型的同步问题,该问题描述的是五个哲学家共用一张圆桌,分别坐在五张椅子上,在圆桌上有五个盘子和五个叉子(如下图),他们的生活方式是交替的进行思考和进餐,思考时不能用餐,用餐时不能思考。平时,一个哲学家进行思考,饥饿时便试图用餐,只有在他同时拿到他的盘子左右两边的两个叉子时才能进餐。进餐完毕后,他会放下叉子继续思考。请写出代码来解决如上的哲学家就餐问题,要求代码返回“当每个哲学家分别需要进食 n 次”时这五位哲学家具体的行为记录。

Python实现哲学家就餐问题实例代码

测试用例:

输入:n = 1 (1<=n<=60,n 表示每个哲学家需要进餐的次数。)

预期输出:

[[4,2,1],[4,1,1],[0,1,1],[2,2,1],[2,1,1],[2,0,3],[2,1,2],[2,2,2],[4,0,3],[4,1,2],[0,2,1],[4,2,2],[3,2,1],[3,1,1],[0,0,3],[0,1,2],[0,2,2],[1,2,1],[1,1,1],[3,0,3],[3,1,2],[3,2,2],[1,0,3],[1,1,2],[1,2,2]]

思路:

输出列表中的每一个子列表描述了某个哲学家的具体行为,它的格式如下:

output[i] = [a, b, c] (3 个整数)

a 哲学家编号。

b 指定叉子:{1 : 左边, 2 : 右边}.

c 指定行为:{1 : 拿起, 2 : 放下, 3 : 吃面}。

如 [4,2,1] 表示 4 号哲学家拿起了右边的叉子。所有自列表组合起来,就完整描述了“当每个哲学家分别需要进食 n 次”时这五位哲学家具体的行为记录。

代码实现

import queue
import threading
import time
import random
 
class CountDownLatch:
  def __init__(self, count):
    self.count = count
    self.condition = threading.Condition()
  def wait(self):
    try:
      self.condition.acquire()
      while self.count > 0:
        self.condition.wait()
    finally:
      self.condition.release()
  def count_down(self):
    try:
      self.condition.acquire()
      self.count -= 1
      self.condition.notifyAll()
    finally:
      self.condition.release()
 
class DiningPhilosophers(threading.Thread):
  def __init__(self, philosopher_number, left_fork, right_fork, operate_queue, count_latch):
    super().__init__()
    self.philosopher_number = philosopher_number
    self.left_fork = left_fork
    self.right_fork = right_fork
    self.operate_queue = operate_queue
    self.count_latch = count_latch
 
  def eat(self):
    time.sleep(0.01)
    self.operate_queue.put([self.philosopher_number, 0, 3])
 
  def think(self):
    time.sleep(random.random())
 
  def pick_left_fork(self):
    self.operate_queue.put([self.philosopher_number, 1, 1])
 
  def pick_right_fork(self):
    self.operate_queue.put([self.philosopher_number, 2, 1])
 
  def put_left_fork(self):
    self.left_fork.release()
    self.operate_queue.put([self.philosopher_number, 1, 2])
 
  def put_right_fork(self):
    self.right_fork.release()
    self.operate_queue.put([self.philosopher_number, 2, 2])
 
  def run(self):
    while True:
      left = self.left_fork.acquire(blocking=False)
      right = self.right_fork.acquire(blocking=False)
      if left and right:
        self.pick_left_fork()
        self.pick_right_fork()
        self.eat()
        self.put_left_fork()
        self.put_right_fork()
        break
      elif left and not right:
        self.left_fork.release()
      elif right and not left:
        self.right_fork.release()
      else:
        time.sleep(0.01)
    print(str(self.philosopher_number) + ' count_down')
    self.count_latch.count_down()
 
if __name__ == '__main__':
  operate_queue = queue.Queue()
  fork1 = threading.Lock()
  fork2 = threading.Lock()
  fork3 = threading.Lock()
  fork4 = threading.Lock()
  fork5 = threading.Lock()
  n = 1
  latch = CountDownLatch(5 * n)
  for _ in range(n):
    philosopher0 = DiningPhilosophers(0, fork5, fork1, operate_queue, latch)
    philosopher0.start()
    philosopher1 = DiningPhilosophers(1, fork1, fork2, operate_queue, latch)
    philosopher1.start()
    philosopher2 = DiningPhilosophers(2, fork2, fork3, operate_queue, latch)
    philosopher2.start()
    philosopher3 = DiningPhilosophers(3, fork3, fork4, operate_queue, latch)
    philosopher3.start()
    philosopher4 = DiningPhilosophers(4, fork4, fork5, operate_queue, latch)
    philosopher4.start()
  latch.wait()
  queue_list = []
  for i in range(5 * 5 * n):
    queue_list.append(operate_queue.get())
  print(queue_list)

总结

到此这篇关于Python实现哲学家就餐问题的文章就介绍到这了,更多相关Python哲学家就餐内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python类的定义、继承及类对象使用方法简明教程
May 08 Python
对python中return和print的一些理解
Aug 18 Python
Python使用django框架实现多人在线匿名聊天的小程序
Nov 29 Python
python实现对excel进行数据剔除操作实例
Dec 07 Python
Python使用matplotlib填充图形指定区域代码示例
Jan 16 Python
Python使用Selenium+BeautifulSoup爬取淘宝搜索页
Feb 24 Python
对python:threading.Thread类的使用方法详解
Jan 31 Python
Python3.5装饰器典型案例分析
Apr 30 Python
python实现静态web服务器
Sep 03 Python
基于python traceback实现异常的获取与处理
Dec 13 Python
Python-for循环的内部机制
Jun 12 Python
Python 按比例获取样本数据或执行任务的实现代码
Dec 03 Python
使用Python实现NBA球员数据查询小程序功能
Nov 09 #Python
Python暴力破解Mysql数据的示例
Nov 09 #Python
python 实现一个图形界面的汇率计算器
Nov 09 #Python
python 读取串口数据的示例
Nov 09 #Python
Cpython解释器中的GIL全局解释器锁
Nov 09 #Python
OpenCV实现机器人对物体进行移动跟随的方法实例
Nov 09 #Python
基于python爬取梨视频实现过程解析
Nov 09 #Python
You might like
《被神捡到的男人》动画化计划进行中!
2020/03/06 日漫
Php Ctemplate引擎开发相关内容
2012/03/03 PHP
php中出现空白页的原因及解决方法汇总
2014/07/08 PHP
护卫神php套件 php版本升级方法(php5.5.24)
2015/05/10 PHP
PHP异常处理定义与使用方法分析
2017/07/25 PHP
ThinkPHP实现的rsa非对称加密类示例
2018/05/29 PHP
php 使用 __call实现重载功能示例
2019/11/18 PHP
JavaScript类和继承 constructor属性
2010/03/04 Javascript
JS 非图片动态loading效果实现代码
2010/04/09 Javascript
javascript调试过程中找不到哪里出错的可能原因
2013/12/16 Javascript
用javascript关闭本窗口不弹出询问框的方法
2014/09/12 Javascript
jquery预加载图片的方法
2015/05/27 Javascript
Javascript实现获取及设置光标位置的方法
2015/07/21 Javascript
JavaScript数据类型判定的总结笔记
2015/07/31 Javascript
plupload+artdialog实现多平台上传文件
2016/07/19 Javascript
html5+CSS 实现禁止IOS长按复制粘贴功能
2016/12/28 Javascript
微信小程序学习(4)-系统配置app.json详解
2017/01/12 Javascript
详解nodeJS之二进制buffer对象
2017/06/03 NodeJs
AngularJS的ng-click传参的方法
2017/06/19 Javascript
Node.js五大应用性能技巧小结(必须收藏)
2017/08/09 Javascript
jquery使用iscorll实现上拉、下拉加载刷新
2017/10/26 jQuery
JavaScript实现左侧菜单效果
2017/12/14 Javascript
koa+jwt实现token验证与刷新功能
2019/05/30 Javascript
vue-cli和v-charts实现可视化图表过程解析
2019/10/08 Javascript
[02:38]DOTA2超级联赛专访Loda 认为IG世界最强
2013/05/27 DOTA
python3使用urllib示例取googletranslate(谷歌翻译)
2014/01/23 Python
numpy.std() 计算矩阵标准差的方法
2018/07/11 Python
Python+OpenCv制作证件图片生成器的操作方法
2019/08/21 Python
手动安装python3.6的操作过程详解
2020/01/13 Python
Canvas与Image互相转换示例代码
2013/08/09 HTML / CSS
用canvas做一个DVD待机动画的实现代码
2019/04/12 HTML / CSS
2014学校领导四风对照检查材料思想汇报
2014/09/23 职场文书
学校运动会简讯
2015/07/20 职场文书
如何书写你的职业生涯规划书?
2019/06/27 职场文书
Python数据分析之pandas函数详解
2021/04/21 Python
P站美图推荐——变身女主角特辑
2022/03/20 日漫