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从ftp下载数据保存实例
Nov 20 Python
寻找网站后台地址的python脚本
Sep 01 Python
Tensorflow简单验证码识别应用
May 25 Python
Windows环境下python环境安装使用图文教程
Mar 13 Python
python使用RNN实现文本分类
May 24 Python
Python离线安装PIL 模块的方法
Jan 08 Python
pandas DataFrame索引行列的实现
Jun 04 Python
pycharm修改file type方式
Nov 19 Python
django多种支付、并发订单处理实例代码
Dec 13 Python
postman和python mock测试过程图解
Feb 22 Python
Python3 requests模块如何模仿浏览器及代理
Jun 15 Python
Python字符串split及rsplit方法原理详解
Jun 29 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 isset()与empty()的使用区别详解
2010/08/29 PHP
Yii1.1中通过Sql查询进行的分页操作方法
2017/03/16 PHP
Thinkphp事务操作实例(推荐)
2017/04/01 PHP
laravel 5.4 + vue + vux + element的环境搭配过程介绍
2018/04/26 PHP
实现laravel 插入操作日志到数据库的方法
2019/10/11 PHP
一个多次搜索+多次传值的解决方案
2007/01/20 Javascript
C#中TrimStart,TrimEnd,Trim在javascript上的实现
2011/01/17 Javascript
javascript 事件处理程序介绍
2012/06/27 Javascript
原生JavaScript实现连连看游戏(附源码)
2013/11/05 Javascript
网站繁简切换的JS遇到页面卡死的解决方法
2014/03/12 Javascript
js操作cookie保存浏览记录的方法
2015/12/25 Javascript
用JS生成UUID的方法实例
2016/03/30 Javascript
jQuery实现布局高宽自适应的简单实例
2016/05/28 Javascript
jquery easyui validatebox remote的使用详解
2016/11/09 Javascript
前端分页功能的实现以及原理(jQuery)
2017/01/22 Javascript
微信小程序开发之数据存储 参数传递 数据缓存
2017/04/13 Javascript
JS实现给json数组动态赋值的方法示例
2020/03/19 Javascript
浅谈node的事件机制
2017/10/09 Javascript
详解基于DllPlugin和DllReferencePlugin的webpack构建优化
2018/06/28 Javascript
Vue数组响应式操作及高阶函数使用代码详解
2020/08/01 Javascript
小程序实现可拖动的悬浮按钮
2020/09/07 Javascript
python求众数问题实例
2014/09/26 Python
python 3.0 模拟用户登录功能并实现三次错误锁定
2017/11/01 Python
浅谈python 线程池threadpool之实现
2017/11/17 Python
python3学习笔记之多进程分布式小例子
2018/02/13 Python
python 画三维图像 曲面图和散点图的示例
2018/12/29 Python
python绘制已知点的坐标的直线实例
2019/07/04 Python
日语专业个人的求职信
2013/12/03 职场文书
特色蛋糕店创业计划书
2014/01/28 职场文书
婚前财产公证书
2014/04/10 职场文书
市场调查策划方案
2014/06/10 职场文书
前台接待岗位职责
2015/02/03 职场文书
2015年实习单位评语
2015/03/25 职场文书
导游词之舟山普陀山
2019/11/06 职场文书
SQL写法--行行比较
2021/08/23 SQL Server
JS实现页面炫酷的时钟特效示例
2022/08/14 Javascript