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操作RabbitMQ服务器消息队列的远程结果返回
Jun 30 Python
Python时间的精准正则匹配方法分析
Aug 17 Python
python+opencv 读取文件夹下的所有图像并批量保存ROI的方法
Jan 10 Python
Pandas读写CSV文件的方法示例
Mar 27 Python
Python3 venv搭建轻量级虚拟环境的步骤(图文)
Aug 09 Python
python实现数据清洗(缺失值与异常值处理)
Dec 02 Python
详解Python修复遥感影像条带的两种方式
Feb 23 Python
pycharm新建Vue项目的方法步骤(图文)
Mar 04 Python
python3 中使用urllib问题以及urllib详解
Aug 03 Python
Python实现壁纸下载与轮换
Oct 19 Python
解决pytorch读取自制数据集出现过的问题
May 31 Python
opencv读取视频并保存图像的方法
Jun 04 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实现首页链接查询 友情链接检查的代码
2010/01/05 PHP
详解php设置session(过期、失效、有效期)
2015/11/12 PHP
PHP Header失效的原因分析及解决方法
2016/11/16 PHP
让iframe子窗体取父窗体地址栏参数(querystring)
2009/10/13 Javascript
JS俄罗斯方块,包含完整的设计理念
2010/12/11 Javascript
JS添加删除一组文本框并对输入信息加以验证判断其正确性
2013/04/11 Javascript
用nodejs写的一个简单项目打包工具
2013/05/11 NodeJs
jsp网页搜索结果中实现选中一行使其高亮
2014/02/17 Javascript
jQuery避免$符和其他JS库冲突的方法对比
2014/02/20 Javascript
js动态删除div元素基本思路及实现代码
2014/05/08 Javascript
使用jQuery实现图片遮罩半透明坠落遮挡
2015/03/16 Javascript
JS+Canvas绘制时钟效果
2020/08/20 Javascript
js实现扫雷小程序的示例代码
2017/09/27 Javascript
axios中cookie跨域及相关配置示例详解
2017/12/20 Javascript
vue裁切预览组件功能的实现步骤
2018/05/04 Javascript
配置node服务器并且链接微信公众号接口配置步骤详解
2019/06/21 Javascript
Vue解决移动端弹窗滚动穿透问题
2020/12/15 Vue.js
全面理解Python中self的用法
2016/06/04 Python
利用python获取某年中每个月的第一天和最后一天
2016/12/15 Python
Python多进程库multiprocessing中进程池Pool类的使用详解
2017/11/24 Python
python 获取一个值在某个区间的指定倍数的值方法
2018/11/12 Python
Python批量生成幻影坦克图片实例代码
2019/06/04 Python
使用OpCode绕过Python沙箱的方法详解
2019/09/03 Python
Python爬虫之Selenium多窗口切换的实现
2020/12/04 Python
HTML5 embed 标签使用方法介绍
2013/08/13 HTML / CSS
加拿大约会网站:EliteSingles.ca
2018/01/12 全球购物
联强国际笔试题面试题
2013/07/10 面试题
编码实现字符串转整型的函数
2012/06/02 面试题
C# .NET面试题
2015/11/28 面试题
急诊科护士自我鉴定
2013/10/14 职场文书
九年级家长会邀请函
2014/01/15 职场文书
本科生就业推荐信
2014/05/19 职场文书
七一建党节演讲稿
2014/09/11 职场文书
2015年仓库管理工作总结
2015/05/25 职场文书
2021-4-3课程——SQL Server查询【2】
2021/04/05 SQL Server
字节飞书面试promise.all实现示例
2022/06/16 Javascript