Python实现哲学家就餐问题实例代码
作者:Snippers 发布时间:2022-09-20 14:10:49
哲学家就餐问题:
哲学家就餐问题是典型的同步问题,该问题描述的是五个哲学家共用一张圆桌,分别坐在五张椅子上,在圆桌上有五个盘子和五个叉子(如下图),他们的生活方式是交替的进行思考和进餐,思考时不能用餐,用餐时不能思考。平时,一个哲学家进行思考,饥饿时便试图用餐,只有在他同时拿到他的盘子左右两边的两个叉子时才能进餐。进餐完毕后,他会放下叉子继续思考。请写出代码来解决如上的哲学家就餐问题,要求代码返回“当每个哲学家分别需要进食 n 次”时这五位哲学家具体的行为记录。
测试用例:
输入: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)
来源:https://blog.csdn.net/Snippers/article/details/109563341


猜你喜欢
- 简介看到了一个能够轻松实现获取系统运行的进程和系统利用率(包括CPU、内存、磁盘、网络等)信息的模块–psutil模块。这次利用psutil
- 最近学习Python接口测试,对于接口测试完全小白。大概一周的学习成果进行总结。1.接口测试:目前涉及到的只是对简单单一的接口进行参数传递,
- 先说下自己的环境,redis是部署在centos上的,爬虫运行在windows上,1. 安装redisyum install -y redi
- 重复性任务总是耗时且无聊,想一想你想要一张一张地裁剪 100 张照片或 Fetch API、纠正拼写和语法等工作,所有这些任务都很耗时,为什
- 本教学使用环境介绍伺服器端:Ubuntu 18.04 LTS资料库:Mariadb 10.1.34(Mysql)语言版本:php 7.3本机
- 编辑距离编辑距离(Edit Distance),又称Levenshtein距离,是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。编
- 1. 从字典创建Dataframe>>> import pandas as pd>>> dict1 =
- 目录结构:testtest/index.phptest/test_zip.ziptest/test_zip<span style=&q
- 首先就是进程、线程、协程讲解老三样。进程: 本质上是一个独立执行的程序,进程是操作系统进行资源分配和调度的基本概念,操作系统进行资
- 设计师不等于美工设计无所不在,但大多数企业不知道如何使用它。现代设计进入中国大概是二十多年的时间,而在国外,尤其在美国在欧洲,大概有一百年的
- 本文介绍一款工具 go-callvis,它能够将 Go 代码的调用关系可视化出来,并提供了可交互式的 web 服务。go get -u gi
- 其实canvas本身很简单,就是去学习它的API,多看实例,多自己动手练习,多总结。但是canvas的API实在是有点多,对于初学者来说,可
- 一、Python简介1.python介绍Python由荷兰数学和计算机科学研究学会的Guido van Rossum 于1990 年代初设计
- 程序运行环境code# -*- coding:utf-8 -*-# -----------------------------------#
- 如下所示:$ary = array( array('t'=>1,'y'=>2), &
- 矩阵创建1、from numpyimport *;a1=array([1,2,3])a2=mat(a1)矩阵与方块列表的区别如下:2、dat
- 今天有个朋友做网页的时候遇到个问题:想保留链接的背景,但又要链接里的文字消失!可是弄了半天一直没办法把这个文字去掉。我想很多学标准的朋友都遇
- 有关 Web 字体的话题正在增多,对 Web 设计师来说,他们并不关注技术细节,不管是 TrueType 的 Hinting 技术
- 如何在win7+Python3.5的环境下安装成功scrapy?通过pip3 install Scrapy直接安装,一般会报错:error:
- 开发过程中,错误免不了。为了纠正错误与规范化。可以使用MS SQL Server的系统存储过程sp_rename与OBJECTPROPERT