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使用rsa加密算法模块模拟新浪微博登录
Jan 22 Python
python pycurl验证basic和digest认证的方法
May 02 Python
python使用turtle库绘制树
Jun 25 Python
浅谈django三种缓存模式的使用及注意点
Sep 30 Python
Python装饰器用法实例分析
Jan 14 Python
解决python3.5 正常安装 却不能直接使用Tkinter包的问题
Feb 22 Python
对python中的float除法和整除法的实例详解
Jul 20 Python
浅析PEP572: 海象运算符
Oct 15 Python
python小白学习包管理器pip安装
Jun 09 Python
Python 解析库json及jsonpath pickle的实现
Aug 17 Python
Python趣味挑战之教你用pygame画进度条
May 31 Python
python分分钟绘制精美地图海报
Feb 15 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
php5 and xml示例
2006/11/22 PHP
phpmailer发送gmail邮件实例详解
2013/06/24 PHP
PHP中模拟处理HTTP PUT请求的例子
2014/07/22 PHP
在win7中搭建Linux+PHP 开发环境
2014/10/08 PHP
jquery 新浪网易的评论块制作
2010/07/01 Javascript
jQuery中bind()方法用法实例
2015/01/19 Javascript
DOM 事件流详解
2015/01/20 Javascript
浅谈EasyUI中Treegrid节点的删除
2015/03/01 Javascript
JavaScript中调用函数的4种方式代码实例
2015/07/08 Javascript
JS判断是否长按某一键的方法
2016/03/02 Javascript
基于jQuery实现Accordion手风琴自定义插件
2020/10/13 Javascript
JS实现淡入淡出图片效果的方法分析
2016/12/20 Javascript
Bootstrap fileinput文件上传预览插件使用详解
2017/05/16 Javascript
Vue实例中生命周期created和mounted的区别详解
2017/08/25 Javascript
详解解决Vue相同路由参数不同不会刷新的问题
2018/10/12 Javascript
JS多个异步请求 按顺序执行next实现解析
2019/09/16 Javascript
vue控制多行文字展开收起的实现示例
2019/10/11 Javascript
使用Python实现BT种子和磁力链接的相互转换
2015/11/09 Python
Python初学者需要注意的事项小结(python2与python3)
2018/09/26 Python
Python实现九宫格式的朋友圈功能内附“马云”朋友圈
2019/05/07 Python
python将邻接矩阵输出成图的实现
2019/11/21 Python
python3.x 生成3维随机数组实例
2019/11/28 Python
django3.02模板中的超链接配置实例代码
2020/02/04 Python
pycharm内无法import已安装的模块问题解决
2020/02/12 Python
记一次Django响应超慢的解决过程
2020/09/17 Python
英国露营设备和户外服装购物网站:Simply Hike
2019/05/05 全球购物
Order by的几种用法
2013/06/16 面试题
《晚上的太阳》教学反思
2014/04/23 职场文书
奥巴马英文演讲稿
2014/05/15 职场文书
销售人员工作自我评价
2014/09/21 职场文书
2014年重阳节老干部座谈会上的讲话稿
2014/09/25 职场文书
中学生旷课检讨书2篇
2014/10/09 职场文书
2016年中秋节晚会领导致辞
2015/11/26 职场文书
2016优秀员工先进事迹材料
2016/02/25 职场文书
Golang 编译成DLL文件的操作
2021/05/06 Golang
教你部署vue项目到docker
2022/04/05 Vue.js