【问题标题】:ThreadPoolExecutor kills last thread prematurelyThreadPoolExecutor 过早地杀死最后一个线程
【发布时间】: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 中找不到一个。另外考虑到我已经很接近了,我真的很想用我的方法来工作。

【问题讨论】:

标签: python multithreading


【解决方案1】:

在您的代码中,self.forks_instance.fork_available[self.num] 将为 Musa 抛出 list index out of range 异常。

此人的 self.num 为 5。但是您的 self.fork_available 数组将具有索引 0, 1, 2, 3, 4。 Musa 线程在这个未捕获的错误上静默崩溃。

简单的解决方法是将 Musa 的 num 值更改为 0:

p = [phil('Platon', 1, forks_instance), phil('Larry', 2, forks_instance), phil('Mark', 3, forks_instance),
     phil('Victor', 4, forks_instance), phil('Musa', 0, forks_instance)]

【讨论】:

  • 哦,是的,我记得 ThreadPoolExecutor 没有显示异常。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多