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操作列表的常用方法分享
Feb 13 Python
python网络编程学习笔记(六):Web客户端访问
Jun 09 Python
Python实现windows下模拟按键和鼠标点击的方法
Mar 13 Python
python使用htmllib分析网页内容的方法
May 08 Python
python简单获取本机计算机名和IP地址的方法
Jun 03 Python
python调用百度REST API实现语音识别
Aug 30 Python
Python3使用Matplotlib 绘制精美的数学函数图形
Apr 11 Python
tensorflow将图片保存为tfrecord和tfrecord的读取方式
Feb 17 Python
python实现扫雷游戏
Mar 03 Python
django模型动态修改参数,增加 filter 字段的方式
Mar 16 Python
Django自定义列表 models字段显示方式
Apr 03 Python
Python正则表达式中flags参数的实例详解
Apr 01 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
ThinkPHP使用心得分享-上传类UploadFile的使用
2014/05/15 PHP
smarty内置函数config_load用法实例
2015/01/22 PHP
PHP实现按之字形顺序打印二叉树的方法
2018/01/16 PHP
Juqery Html(),append()等方法的Bug解决方法
2010/12/13 Javascript
js实现在文本框光标处添加字符的方法介绍
2012/11/24 Javascript
41个Web开发者必须收藏的JavaScript实用技巧
2016/07/22 Javascript
Javascript OOP之面向对象
2016/07/31 Javascript
AngularJs页面筛选标签小功能
2016/08/01 Javascript
jQuery使用animate实现ul列表项相互飘动效果示例
2016/09/16 Javascript
微信小程序  audio音频播放详解及实例
2016/11/02 Javascript
cordova入门基础教程及使用中遇到的一些问题总结
2017/11/14 Javascript
微信小程序本地存储实现每日签到、连续签到功能
2019/10/09 Javascript
微信小程序tabBar设置实例解析
2019/11/14 Javascript
JS实现鼠标移动拖尾
2020/12/27 Javascript
[40:53]完美世界DOTA2联赛PWL S3 Magma vs DLG 第二场 12.18
2020/12/20 DOTA
python格式化字符串实例总结
2014/09/28 Python
部署Python的框架下的web app的详细教程
2015/04/30 Python
在Python中定义和使用抽象类的方法
2016/06/30 Python
Python使用functools模块中的partial函数生成偏函数
2016/07/02 Python
python中for循环把字符串或者字典添加到列表的方法
2019/07/20 Python
使用Django和Postgres进行全文搜索的实例代码
2020/02/13 Python
Python3实现打印任意宽度的菱形代码
2020/04/12 Python
python3+selenium获取页面加载的所有静态资源文件链接操作
2020/05/04 Python
MCM英国官网:奢侈皮具制品
2017/04/18 全球购物
英国最大的宝石首饰超市:QP Jewellers
2018/09/23 全球购物
联强国际笔试题面试题
2013/07/10 面试题
如何用Java判断一个文件或目录是否存在
2012/11/19 面试题
生物科学专业个人求职信范文
2013/12/07 职场文书
单位门卫岗位职责
2013/12/20 职场文书
父亲生日宴会答谢词
2014/01/10 职场文书
优秀教师工作感言
2014/02/16 职场文书
优乐美广告词
2014/03/14 职场文书
社区党员群众路线教育实践活动心得体会
2014/11/03 职场文书
2015年乡镇统计工作总结
2015/04/22 职场文书
小学二年级班主任工作经验交流材料
2015/11/02 职场文书
Vue提供的三种调试方式你知道吗
2022/01/18 Vue.js