【发布时间】:2019-11-15 08:24:18
【问题描述】:
我的任务是为dining philosophers problem 提供我自己的解决方案 在 Python 3 中。下面的代码是我的解决方案。在大多数情况下,它按我的预期工作,所以我认为我已经相当接近了。
import time
import threading
from concurrent.futures import ThreadPoolExecutor
class forks:
lock = threading.RLock()
fork_available = []
def __init__(self):
for i in range(5):
self.fork_available.append(True)
class phil:
def __init__(self, name, num, fork_instance):
self.name = name
self.num = num
self.forks_instance = forks_instance
def behaviour(self):
while True:
print(f'{self.name} is thinking\n')
time.sleep(2)
print(f'{self.name} is hungry, reaching for the forks:\n')
with forks_instance.lock:
if self.forks_instance.fork_available[self.num] is True and self.forks_instance.fork_available[
(self.num + 1) % 5] is True:
self.forks_instance.fork_available[self.num] = False
self.forks_instance.fork_available[(self.num + 1) % 5] = False
print(f'{self.name} is eating\n')
time.sleep(3)
print(f'{self.name} is done, putting down forks\n')
self.forks_instance.fork_available[self.num] = True
self.forks_instance.fork_available[(self.num + 1) % 5] = True
if __name__ == '__main__':
forks_instance = forks()
with ThreadPoolExecutor(max_workers=5) as ex:
p = [phil('Platon', 1, forks_instance), phil('Larry', 2, forks_instance), phil('Mark', 3, forks_instance),
phil('Victor', 4, forks_instance), phil('Musa', 5, forks_instance)]
for person in p:
ex.submit(person.behaviour)
但是,其中一个问题是最后一个人 - 在这种情况下是 Musa - 不会尝试伸手去拿叉子或吃东西。我很肯定它实际上是由执行程序部署的,因为程序总是以此开头:
Platon is thinking
Larry is thinking
Mark is thinking
Victor is thinking
Musa is thinking
但在那之后,最后一个线程什么也不做。
我遇到的另一个问题是控制台有时会跳过换行符:
Larry is hungry, reaching for the forks:Victor is hungry, reaching for the forks:Mark is hungry, reaching for the
虽然有时它是正确的:
Victor is hungry, reaching for the forks:
Larry is done, putting down forks
Larry is thinking
Mark is eating
感谢任何有关解决这两个问题的帮助。
我知道这个问题在网上有很多解决方案,包括 Python,尽管我在 Python 3 中找不到一个。另外考虑到我已经很接近了,我真的很想用我的方法来工作。
【问题讨论】:
-
根据这个 SO 线程打印到标准输出不是线程安全的。这可能是您的换行符丢失的原因。 stackoverflow.com/questions/7687862/…
标签: python multithreading