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抓取某汽车网数据解析html存入excel示例
Dec 04 Python
Python编写登陆接口的方法
Jul 10 Python
使用Python进行目录的对比方法
Nov 01 Python
使用Python和Scribus创建一个RGB立方体的方法
Jul 17 Python
Python安装selenium包详细过程
Jul 23 Python
python中append实例用法总结
Jul 30 Python
Python根据服务获取端口号的方法
Sep 25 Python
如何基于python操作json文件获取内容
Dec 24 Python
python实现双色球随机选号
Jan 01 Python
python等差数列求和公式前 100 项的和实例
Feb 25 Python
python 基于opencv 实现一个鼠标绘图小程序
Dec 11 Python
关于django python manage.py startapp 应用名出错异常原因解析
Dec 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
用mysql触发器自动更新memcache的实现代码
2009/10/11 PHP
php获取用户IPv4或IPv6地址的代码
2012/11/15 PHP
PHP FATAL ERROR: CALL TO UNDEFINED FUNCTION BCMUL()解决办法
2014/05/04 PHP
ThinkPHP3.1新特性之对分组支持的改进与完善概述
2014/06/19 PHP
PHP生成可点击刷新的验证码简单示例
2016/05/13 PHP
用JS实现一个页面多个css样式实现
2008/05/29 Javascript
用jquery和json从后台获得数据集的代码
2011/11/07 Javascript
JavaScript:Div层拖动效果实例代码
2013/08/06 Javascript
JavaScript中字符串分割函数split用法实例
2015/04/07 Javascript
js运动应用实例解析
2015/12/28 Javascript
jQuery ajax分页插件实例代码
2016/01/27 Javascript
一款简单的jQuery图片标注效果附源码下载
2016/03/22 Javascript
jQuery获取当前点击的对象元素(实现代码)
2016/05/19 Javascript
JavaScript浮点数及运算精度调整详解
2016/10/21 Javascript
jQuery的Read()方法代替原生JS详解
2016/11/08 Javascript
Vue.js 2.0 移动端拍照压缩图片上传预览功能
2017/03/06 Javascript
详解vue-router和vue-cli以及组件之间的传值
2017/07/04 Javascript
使用cx_freeze把python打包exe示例
2014/01/24 Python
Python不规范的日期字符串处理类
2014/06/10 Python
微信跳一跳辅助python代码实现
2018/01/05 Python
python os.listdir按文件存取时间顺序列出目录的实例
2018/10/21 Python
在Pycharm中执行scrapy命令的方法
2019/01/16 Python
python实现大转盘抽奖效果
2019/01/22 Python
Python爬虫中Selenium实现文件上传
2020/12/04 Python
详解css3 object-fit属性
2018/07/27 HTML / CSS
美国网上眼镜商城:Zenni Optical
2016/11/20 全球购物
中国网上药店领导者:1药网
2017/02/16 全球购物
美国正宗设计师眼镜在线零售商:EYEZZ
2019/03/23 全球购物
马歇尔耳机官网:Marshall Headphones
2020/02/04 全球购物
违反课堂纪律检讨书
2014/01/19 职场文书
小学生节约用水倡议书
2014/05/15 职场文书
教师考核材料
2014/05/21 职场文书
2015年底工作总结范文
2015/05/15 职场文书
团结友爱主题班会
2015/08/13 职场文书
python数据库批量插入数据的实现(executemany的使用)
2021/04/30 Python
使用Pytorch训练two-head网络的操作
2021/05/28 Python