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实现下载网易云音乐的高清MV
Mar 16 Python
Python抓取电影天堂电影信息的代码
Apr 07 Python
python3+PyQt5图形项的自定义和交互 python3实现page Designer应用程序
Jul 20 Python
JSON文件及Python对JSON文件的读写操作
Oct 07 Python
python+flask实现API的方法
Nov 21 Python
python NumPy ndarray二维数组 按照行列求平均实例
Nov 26 Python
在OpenCV里实现条码区域识别的方法示例
Dec 04 Python
Python+Redis实现布隆过滤器
Dec 08 Python
Pytorch 计算误判率,计算准确率,计算召回率的例子
Jan 18 Python
python使用PIL剪切和拼接图片
Mar 23 Python
pytorch随机采样操作SubsetRandomSampler()
Jul 07 Python
Pytest中skip和skipif的具体使用方法
Jun 30 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
晶体管来复再生式二管收音机
2021/03/02 无线电
PHP chmod 函数与批量修改文件目录权限
2010/05/10 PHP
javascript数组与php数组的地址传递及值传递用法实例
2015/01/22 PHP
php线性表的入栈与出栈实例分析
2015/06/12 PHP
Thinkphp自定义代码生成工具及用法说明(附下载地址)
2016/05/27 PHP
浅析PHP7新功能及语法变化总结
2016/06/17 PHP
LaravelS通过Swoole加速Laravel/Lumen详解
2018/03/02 PHP
PHP实现的策略模式示例
2019/03/20 PHP
laravel-admin 管理平台获取当前登陆用户信息的例子
2019/10/08 PHP
javascript中length属性的探索
2011/07/31 Javascript
JavaScript之引用类型介绍
2012/08/10 Javascript
javascript获取和判断浏览器窗口、屏幕、网页的高度、宽度等
2014/05/08 Javascript
JS实现点击按钮控制Div变宽、增高及调整背景色的方法
2015/08/05 Javascript
javascript中html字符串转化为jquery dom对象的方法
2015/08/27 Javascript
JavaScript学习小结之使用canvas画“哆啦A梦”时钟
2016/07/24 Javascript
AngularJS基础 ng-value 指令简单示例
2016/08/03 Javascript
JS 插件dropload下拉刷新、上拉加载使用小结
2017/04/13 Javascript
react系列从零开始_简单谈谈react
2017/07/06 Javascript
JavaScript 值类型和引用类型的初次研究(推荐)
2017/07/19 Javascript
Ionic学习日记实现验证码倒计时
2018/02/08 Javascript
在react-router4中进行代码拆分的方法(基于webpack)
2018/03/08 Javascript
Vuejs2 + Webpack框架里,模拟下载的实例讲解
2018/09/05 Javascript
jQuery实现的中英文切换功能示例
2019/01/11 jQuery
[01:04:32]DOTA2-DPC中国联赛 正赛 Aster vs LBZS BO3 第二场 2月23日
2021/03/11 DOTA
videocapture库制作python视频高速传输程序
2013/12/23 Python
CentOS6.9 Python环境配置(python2.7、pip、virtualenv)
2019/05/06 Python
详解python实现交叉验证法与留出法
2019/07/11 Python
PyCharm 无法 import pandas 程序卡住的解决方式
2020/03/09 Python
Python基于模块Paramiko实现SSHv2协议
2020/04/28 Python
Feelunique德国官方网站:欧洲最大的在线美容零售商
2019/07/20 全球购物
都柏林通行卡/城市通票:The Dublin Pass
2020/02/16 全球购物
毕业生求职信的经典写法
2014/01/31 职场文书
2014大学班主任工作总结
2014/11/08 职场文书
关于antd tree 和父子组件之间的传值问题(react 总结)
2021/06/02 Javascript
浅析Django接口版本控制
2021/06/26 Python
什么是动态刷新率DRR? Windows11动态刷新率功能介绍
2021/11/21 数码科技