餐饮哲学家代码操作系统

时间:2018-03-27 12:15:12

标签: python python-3.x operating-system deadlock livelock

程序:

        import threading
        import time
        import random
        global spoons
        spoons = [1, 1, 1, 1, 1]


    class mythread(threading.Thread):
        running = True

        def __init__(self, name, number):
            threading.Thread.__init__(self)
            self.name = name
            self.number = number

        def run(self):
            while self.running:
                time.sleep( random.uniform(5,10))
                print ('{} is hungry.'.format(self.name))
                self.check()

        def eat(self):
            global spoons
            z=self.number
            print("{} is eating\n".format(self.name))
            time.sleep(random.uniform(1, 5))
            print("{} has finished eating\n".format(self.name))
            if(z == 1):
                spoons[z] = spoons[4] = 1
            else:
                spoons[z] = spoons[z - 1] = 1

        def wait(self):
            time.sleep(1)
            self.check()

        def check(self):
            global spoons
            z = self.number
            if(z % 2 != 0):
                if(spoons[z - 1] == 1):
                    spoons[z - 1] = 0
                    if(z == 1):
                        if(spoons[4] == 1):
                            spoons[4] = 0
                            self.eat()
                        else:
                            self.wait()
                    else:
                        if(spoons[z - 2] == 1):
                            spoons[z - 2] = 0
                            self.eat()
                        else:
                            self.wait()
                else:
                    self.wait()
            else:
                if(spoons[z - 2] == 1):
                    spoons[z - 2] = 0
                    if(spoons[z - 1] == 1):
                        spoons[z - 1] = 0
                        self.eat()
                    else:
                        self.wait()
                else:
                    self.wait()


    Name=['p1', 'p2', 'p3', 'p4', 'p5']
    philosophers= [mythread(name = Name[i % 5], number = (i + 1) % 5)
                for i in range(5)]


    for p in philosophers:
        p.start()


    time.sleep(100)
    mythread.running = False
    print("Now we're finishing.")

输出:

Exception in thread p3:
Traceback (most recent call last):
  File "C:\Users\devda\AppData\Local\Programs\Python\Python36\lib\threading.py", line 916, in _bootstrap_inner
    self.run()
  File "D:/ANIKET/osproject/dining_philosophers_probelm.py", line 22, in run
    def eat(self):
  File "D:/ANIKET/osproject/dining_philosophers_probelm.py", line 56, in check
    self.wait()
  File "D:/ANIKET/osproject/dining_philosophers_probelm.py", line 37, in wait
    def check(self):
  File "D:/ANIKET/osproject/dining_philosophers_probelm.py", line 58, in check
    if(spoons[z - 2] == 1):
  File "D:/ANIKET/osproject/dining_philosophers_probelm.py", line 37, in wait
    def check(self):
  File "D:/ANIKET/osproject/dining_philosophers_probelm.py", line 58, in check
    if(spoons[z - 2] == 1):
  File "D:/ANIKET/osproject/dining_philosophers_probelm.py", line 37, in wait
    def check(self):
  File "D:/ANIKET/osproject/dining_philosophers_probelm.py", line 58, in check
    if(spoons[z - 2] == 1):
  File "D:/ANIKET/osproject/dining_philosophers_probelm.py", line 37, in wait
    def check(self):
  File "D:/ANIKET/osproject/dining_philosophers_probelm.py", line 58, in check
    if(spoons[z - 2] == 1):
  File "D:/ANIKET/osproject/dining_philosophers_probelm.py", line 37, in wait
    def check(self):
  File "D:/ANIKET/osproject/dining_philosophers_probelm.py", line 58, in check
    if(spoons[z - 2] == 1):
  File "D:/ANIKET/osproject/dining_philosophers_probelm.py", line 37, in wait
    def check(self):
  File "D:/ANIKET/osproject/dining_philosophers_probelm.py", line 58, in check
    if(spoons[z - 2] == 1):
  File "D:/ANIKET/osproject/dining_philosophers_probelm.py", line 37, in wait
    def check(self):
  File "D:/ANIKET/osproject/dining_philosophers_probelm.py", line 58, in check

它正在工作一段时间然后显示错误。 我认为这是合乎逻辑的错误。但我似乎无法理解是什么 我使用的逻辑是偶数编号的哲学家将首先采用右叉,奇数编号的哲学家将首先使用左叉。 这个逻辑用在我的代码中的check()函数中 另外因为我使用了很多递归调用,所以这个错误是由于递归堆栈的耗尽而发生的?

1 个答案:

答案 0 :(得分:1)

代码:

import threading
import random
import time

class Philosopher(threading.Thread):
    running = True
    def __init__(self, xname, forkOnLeft, forkOnRight):
        threading.Thread.__init__(self)
        self.name = xname
        self.forkOnLeft = forkOnLeft
        self.forkOnRight = forkOnRight

    def run(self):
        while(self.running):

            time.sleep( random.uniform(3,13))
            print ('%s is hungry.' % self.name)
            self.dine()

    def dine(self):
        fork1, fork2 = self.forkOnLeft, self.forkOnRight
        while self.running:
            fork1.acquire(True)
            locked = fork2.acquire(False)
            if locked: break
            fork1.release()
            print ('%s swaps forks' % self.name)
            fork1, fork2 = fork2, fork1
        else:
            return

        self.dining()
        fork2.release()
        fork1.release()

    def dining(self):           
        print ('%s starts eating '% self.name)
        time.sleep(random.uniform(1,10))
        print ('%s finishes eating and leaves to think.' % self.name)

def DiningPhilosophers():
    forks = [threading.Lock() for n in range(5)]
    philosopherNames = ('1','2','3','4', '5')

    philosophers= [Philosopher(philosopherNames[i], forks[i%5], forks[(i+1)%5])
            for i in range(5)]


    Philosopher.running = True
    for p in philosophers:
        p.start()
    time.sleep(30)
    Philosopher.running = False

DiningPhilosophers()

尝试此检查是否有效:)