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 相关文章推荐
Tornado Web服务器多进程启动的2个方法
Aug 04 Python
Python3.2中的字符串函数学习总结
Apr 23 Python
Python实现二维有序数组查找的方法
Apr 27 Python
详解python实现线程安全的单例模式
Mar 05 Python
python读写csv文件方法详细总结
Jul 05 Python
Python pandas实现excel工作表合并功能详解
Aug 29 Python
基于Python实现ComicReaper漫画自动爬取脚本过程解析
Nov 11 Python
Python函数的迭代器与生成器的示例代码
Jun 18 Python
Python 字符串池化的前提
Jul 03 Python
PyCharm vs VSCode,作为python开发者,你更倾向哪种IDE呢?
Aug 17 Python
如何在Python3中使用telnetlib模块连接网络设备
Sep 21 Python
python+selenium实现12306模拟登录的步骤
Jan 21 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
使用sockets:从新闻组中获取文章(二)
2006/10/09 PHP
Laravel框架下的Contracts契约详解
2020/03/17 PHP
Javascript 个人笔记(没有整理,很乱)
2007/07/07 Javascript
jquery 插件开发 extjs中的extend用法小结
2013/01/04 Javascript
基于jquery的文字向上跑动类似跑马灯的效果
2014/09/22 Javascript
jQuery实现html元素拖拽
2015/07/21 Javascript
JS特效实现图片自动播放并可控的效果
2015/07/31 Javascript
jQuery实现自动与手动切换的滚动新闻特效代码分享
2015/08/27 Javascript
分步解析JavaScript实现tab选项卡自动切换功能
2016/01/25 Javascript
深入浅析JavaScript中的Function类型
2016/07/09 Javascript
基于IView中on-change属性的使用详解
2018/03/15 Javascript
使用react render props实现倒计时的示例代码
2018/12/06 Javascript
JS中的模糊查询功能
2019/12/08 Javascript
vue 中的 render 函数作用详解
2020/02/28 Javascript
vue.js实现简单购物车功能
2020/05/30 Javascript
jQuery 实现DOM元素拖拽交换位置的实例代码
2020/07/14 jQuery
python实现apahce网站日志分析示例
2014/04/02 Python
python中正则表达式的使用详解
2014/10/17 Python
编写Python脚本使得web页面上的代码高亮显示
2015/04/24 Python
Python实现多线程抓取网页功能实例详解
2017/06/08 Python
用Python实现随机森林算法的示例
2017/08/24 Python
python实现支付宝当面付(扫码支付)功能
2018/05/30 Python
Python利用Django如何写restful api接口详解
2018/06/08 Python
python实现飞机大战微信小游戏
2020/03/21 Python
Django使用redis缓存服务器的实现代码示例
2019/04/28 Python
Python如何使用字符打印照片
2020/01/03 Python
详解python内置常用高阶函数(列出了5个常用的)
2020/02/21 Python
Python页面加载的等待方式总结
2021/02/28 Python
JD Sports西班牙:英国领先的运动服装公司
2020/01/06 全球购物
乐高瑞士官方商店:LEGO CH
2020/08/16 全球购物
社区服务活动报告
2015/02/05 职场文书
学校世界艾滋病日宣传活动总结
2015/05/05 职场文书
2015年教研员工作总结
2015/05/26 职场文书
初中政教处工作总结
2015/08/12 职场文书
创业计划书之物流运送
2019/09/17 职场文书
Python如何识别银行卡卡号?
2021/06/10 Python