白冥 发表于 2024-5-18 01:46:17

【并发编程】哲学家饥饿问题的代码实现

import threading
import time
class Consumption:
    def __init__(self, counts):
      self.counts=counts
      self.forks=
      self.philosophers=
    def consumption(self, position):
      philosopher=self.philosophers
      left_fork, right_fork = self.forks, self.forks[(position+1) % self.counts]
      first_fork = left_fork if position%2 == 0 else right_fork
      second_fork=right_fork if position%2==0 else left_fork
      whilenot philosopher.leave:
            philosopher.with_forks(first_fork, second_fork)
class Fork:
    def __init__(self):
      self.lock=threading.Lock()
    def wait(self):
      try:
            self.lock.acquire(timeout=3)
            return True
      except threading.Timeout:
            return False
    def signal(self):
      self.lock.release()
class Philosopher:
    def __init__(self,position):
      self.satiety=50
      self.leave=False
      self.position=position
      self.forks=[]
    def with_forks(self, *forks):
      for fork in forks:
            if not fork.wait():
                self.reduce()
                return
            else:
                self.forks.append(fork)
      self.eat()
    def put_forks(self):
      counts=len(self.forks)
      for i in range(counts):
            self.forks.signal()
            self.forks.pop(i)
    def eat(self,):
      time.sleep(10)
      self.rise()
    def anger(self):
      self.put_forks()
      self.leave=True
      print(f"Dr.{self.position} is so hungry that he can't bear it and decide to leave.")
    def be_full(self,philosopher):
      self.put_forks()
      self.leave=True
      print(f"Dr.{self.position} feel satisfied and leave the table.")
    def rise(self):
      if self.satiety>=0 and self.satiety<100:
            self.satiety+=10
      else:
            self.be_full()
    def reduce(self):
      if self.satiety>=0 and self.satiety<100:
            self.satiety-=10
      else:
            self.anger()
if __name__=="__main__":
    counts=5
    consumption=Consumption(counts)
    for i in range(counts):
          threading.Thread(target=consumption.consumption,args=(i,)).start()      哲学家饥饿问题是计算机科学家迪杰斯特拉(Dijkstra)提出的经典并发问题。
      有5个哲学家(线程)坐在圆桌上,每个哲学家之间放着一把叉子。一个哲学家要吃饭,他需要左右两边的叉子。如果相邻的两个哲学家同时试图拿起中间的叉子,就可能产生死锁。


[*]Consumption类初始化时,根据传入的哲学家数量(counts)创建相应数量的叉子和哲学家对象。
[*]consumption方法用于模拟某位哲学家的就餐过程。根据哲学家的位置,确定他需要获取的叉子的顺序(先左后右或先右后左,以避免死锁),并尝试拿起叉子吃饭。
[*]Fork类表示叉子,包含一个线程锁来控制对叉子的访问。wait方法尝试获取锁,如果获取成功返回True,否则在设定的超时时间后返回False。signal方法用于释放锁。
[*]Philosopher类代表哲学家,包含哲学家的状态(如满意度、是否离开等)和与叉子交互的方法(如拿起叉子、放下叉子等)。
[*]在Philosopher类中,with_forks方法尝试让哲学家拿起左右两边的叉子,如果拿起成功则开始吃饭,否则根据哲学家的满意度决定是否离开。
[*]eat方法模拟吃饭过程,吃完后增加哲学家的满意度。
[*]anger和be_full方法分别模拟哲学家因饥饿而愤怒离开和吃饱后满意离开的情况。
[*]rise和reduce方法分别用于增加和减少哲学家的满意度。


夏漏光微 发表于 2024-5-18 02:15:49

好像可以用于解决同时请求量过大的问题
:shutup:不过我也不是码农,就是这样想想

娱乐法师火布偶 发表于 2024-5-18 02:56:02

实际应用中解决死锁的策略好像还挺多的

轮回2L 发表于 2024-5-18 06:17:22

看了下解释稍微有点懂了惹XD

Burry 发表于 2024-5-18 07:35:24

很长一段代码,看下了下面介绍,有点懂又没懂。

nullnull 发表于 2024-5-18 07:57:49

死锁以外 还有未达成指令后同时再激活还是同时抢一个叉子的活锁问题之类的
总感觉是什么奥数还是啥地方看到过的问题

li漠北 发表于 2024-5-18 09:23:52

看不懂,我的天,论坛已经进化到这么专业了吗?祝你们讨论的开心吧

koh 发表于 2024-5-18 09:32:27

懂了!这个程序就是为了最大程度上让每一个人都只拿一件东西,且不重复

黑达克 发表于 2024-5-18 11:53:01

虽然有点跑题,但哲学家这种好像都是死后才会出名/更加出名,所以…… 要不还是饿死几个吧;P

深暗幽狼 发表于 2024-5-18 12:20:32

用代码跑个现实问题,emmm想到了一张图:

七七猫 发表于 2024-5-18 14:46:21

看起来有点像嵌入式编程里的优先级问题,不过不知道解决思路是不是差不多的

毛茸茸兽兽 发表于 2024-5-18 15:28:03

吼(´×ω×`)看了8楼楼主的解释大概明白了些欸~也可以编辑进帖子里方便菜鸡们(咱)理解的哇~

wdhgzdhcxb 发表于 2024-5-18 21:43:46

把想要解决的问题是什么搞懂我就满足了,代码实在无能为力{:4_114:}{:4_114:}

饥渴难耐的G 发表于 2024-5-18 22:00:37

搞不懂,但知道应该很实用吧,也是才疏学浅了

zhuovboyan 发表于 2024-5-18 23:39:24

0- 0 稍微看了大家科普才明白了一点 今天也是涨知识的一天呢

Dasteroid 发表于 2024-5-19 17:00:38

我记得这个可以靠硬件的信号系统解决吧

BDonde 发表于 2024-5-19 20:55:07

在课上学过的经典同步问题,又一次的感受和理解

bigbigbig3 发表于 2024-5-22 21:08:53

是我看不懂的样子
氮素楼主很棒请加油噜

chouki 发表于 2024-5-24 20:43:10

所有这个脚本是做嘛的?{:6_194:}看了楼上面的回贴依旧不明白

森森冥 发表于 2024-5-25 23:39:56

完蛋,根本看不懂惹(´•ω•̥`)
页: [1] 2
查看完整版本: 【并发编程】哲学家饥饿问题的代码实现