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去掉字符串中空格的方法
Mar 11 Python
pip install urllib2不能安装的解决方法
Jun 12 Python
python把1变成01的步骤总结
Feb 27 Python
如何用Python破解wifi密码过程详解
Jul 12 Python
对Pytorch中nn.ModuleList 和 nn.Sequential详解
Aug 18 Python
Python 文件操作之读取文件(read),文件指针与写入文件(write),文件打开方式示例
Sep 29 Python
tensorflow estimator 使用hook实现finetune方式
Jan 21 Python
Python chardet库识别编码原理解析
Feb 18 Python
python扫描线填充算法详解
Feb 19 Python
Python 图片处理库exifread详解
Feb 25 Python
Flask中jinja2的继承实现方法及实例
Mar 03 Python
OpenCV-Python实现油画效果的实例
Jun 08 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
浅谈PHP语法(1)
2006/10/09 PHP
Windows2003下php5.4安装配置教程(Apache2.4)
2016/06/30 PHP
ThinkPHP开发--使用七牛云储存
2017/09/14 PHP
红米手机抢购的js代码
2014/03/10 Javascript
jQuery使用post方法提交数据实例
2015/03/25 Javascript
js实现同一页面多个不同运动效果的方法
2015/04/10 Javascript
avalon js实现仿google plus图片多张拖动排序附源码下载
2015/09/24 Javascript
JS设置下拉列表框当前所选值的方法
2015/12/22 Javascript
实例讲解使用原生JavaScript处理AJAX请求的方法
2016/05/10 Javascript
BootStrap下jQuery自动完成的样式调整
2016/05/30 Javascript
js计算系统当前日期是星期几的方法
2016/07/14 Javascript
jQuery leonaScroll 1.1 自定义滚动条插件(推荐)
2016/09/17 Javascript
Vue.js第四天学习笔记(组件)
2016/12/02 Javascript
搭建Bootstrap离线文档的方法
2016/12/02 Javascript
canvas滤镜效果实现代码
2017/02/06 Javascript
Vue的移动端多图上传插件vue-easy-uploader的示例代码
2017/11/27 Javascript
基于Koa2写个脚手架模拟接口服务的方法
2018/11/27 Javascript
axios异步提交表单数据的几种方法
2019/08/11 Javascript
[01:00:44]DOTA2上海特级锦标赛主赛事日 - 3 败者组第三轮#1COL VS Alliance第三局
2016/03/04 DOTA
Python判断Abundant Number的方法
2015/06/15 Python
Python+Pika+RabbitMQ环境部署及实现工作队列的实例教程
2016/06/29 Python
python爬虫_微信公众号推送信息爬取的实例
2017/10/23 Python
浅谈DataFrame和SparkSql取值误区
2018/06/09 Python
用python实现学生管理系统
2020/07/24 Python
详解BeautifulSoup获取特定标签下内容的方法
2020/12/07 Python
css3针对移动端卡顿问题的解决(动画性能优化)
2020/02/14 HTML / CSS
Clearly新西兰:购买眼镜、太阳镜和隐形眼镜
2018/04/26 全球购物
一套软件开发工程师笔试题
2015/05/18 面试题
见习期自我鉴定
2013/11/07 职场文书
夏季奶茶店创业计划书
2014/01/16 职场文书
新闻编辑求职信
2014/07/13 职场文书
导盲犬小Q观后感
2015/06/11 职场文书
运动会通讯稿100字
2015/07/20 职场文书
服装店员工管理制度
2015/08/07 职场文书
幼儿园亲子活动感想
2015/08/07 职场文书
Vue接口封装的完整步骤记录
2021/05/14 Vue.js