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 相关文章推荐
使用PDB模式调试Python程序介绍
Apr 05 Python
python通过邮件服务器端口发送邮件的方法
Apr 30 Python
详解Python爬虫的基本写法
Jan 08 Python
Python构建图像分类识别器的方法
Jan 12 Python
python tools实现视频的每一帧提取并保存
Mar 20 Python
wxpython绘制音频效果
Nov 18 Python
python range实例用法分享
Feb 06 Python
Python ATM功能实现代码实例
Mar 19 Python
Anaconda+VSCode配置tensorflow开发环境的教程详解
Mar 30 Python
python爬虫容易学吗
Jun 02 Python
Keras 利用sklearn的ROC-AUC建立评价函数详解
Jun 15 Python
java关于string最常出现的面试题整理
Jan 18 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/03 冲泡冲煮
php自动跳转中英文页面
2008/07/29 PHP
php 无限级数据JSON格式及JS解析
2010/07/17 PHP
PHP MVC框架skymvc支持多文件上传
2016/05/26 PHP
静态html文件执行php语句的方法(推荐)
2016/11/21 PHP
PHP项目多语言配置平台实现过程解析
2020/05/18 PHP
Javascript 验证上传图片大小[客户端]
2009/08/01 Javascript
Lazy Load 延迟加载图片的jQuery插件中文使用文档
2012/10/18 Javascript
jQuery中end()方法用法实例
2015/01/08 Javascript
Javascript writable特性介绍
2015/02/27 Javascript
jQuery拖拽插件gridster使用指南
2015/04/21 Javascript
js实现的简单图片浮动效果完整实例
2016/05/10 Javascript
微信公众号-获取用户信息(网页授权获取)实现步骤
2016/10/21 Javascript
微信小程序 input输入框控件详解及实例(多种示例)
2016/12/14 Javascript
yii form 表单提交之前JS在提交按钮的验证方法
2017/03/15 Javascript
Angularjs2不同组件间的通信实例代码
2017/05/06 Javascript
使用Node.js实现RESTful API的示例
2017/08/01 Javascript
Babel 入门教程学习笔记
2018/06/13 Javascript
Vue中使用方法、计算属性或观察者的方法实例详解
2018/10/31 Javascript
Vue组件实现触底判断
2019/06/26 Javascript
零基础写python爬虫之爬虫框架Scrapy安装配置
2014/11/06 Python
python使用pygame框架实现推箱子游戏
2018/11/20 Python
通过实例解析Python RPC实现原理及方法
2020/07/07 Python
用python写爬虫简单吗
2020/07/28 Python
python如何实时获取tcpdump输出
2020/09/16 Python
HTML5 通过Vedio标签实现视频循环播放的示例代码
2020/08/05 HTML / CSS
欧铁通票官方在线销售网站:Eurail.com
2017/10/14 全球购物
东南亚排名第一的服务市场:kaodim
2019/03/28 全球购物
Under Armour安德玛意大利官网:美国高端运动科技品牌
2020/01/16 全球购物
测绘专业大学生职业生涯规划书
2014/02/10 职场文书
个人安全生产承诺书
2014/05/22 职场文书
报效祖国演讲稿
2014/09/15 职场文书
授权委托书
2015/01/28 职场文书
网络营销实训总结
2015/08/03 职场文书
乔迁新居祝福语
2019/11/04 职场文书
关于React Native使用axios进行网络请求的方法
2021/08/02 Javascript