Python并发Futures的executor.submit超时

5

我想使用多线程并设置每个线程的超时时间。我已经使用了以下代码:

import concurrent.futures

class Action:

    def __init(self):
        self.name = 'initial'

    def define_name(self):
        # In my real code this method is executed during 30-60 seconds
        self.name = 'name'

action_list = [
    Action(),
    Action(),
]

with concurrent.futures.ThreadPoolExecutor(
    max_workers = 20
) as executor:
    for action_item in action_list:
        # without timeout arg, it works !
        executor.submit(action_item.define_name, timeout=1)

for action_item in action_list:
    print(action_item.name)

我已经看到了这篇文章如何在 concurrent.futures 中使用超时?但是我不需要使用 result 方法。

Python 文档对我没有帮助 (https://docs.python.org/3/library/concurrent.futures.html)。它展示了如何使用 map 方法来定义超时,但没有使用 submit。

您知道如何使用 executor.submit 方法来定义超时吗?

编辑:这个例子非常简单。在我的实际情况中,我有一个包含 15000+ 个项目的列表。每个由 executor.submit() 运行的操作需要 30-60 秒。但是一些项目需要超过 5 分钟的时间,我想要排除这些项目的超时。

编辑2:我想在超时后停止一个线程。但我不想使用 Thread 对象。因此,这篇文章 (有没有一种方法可以在 Python 中杀死线程? ) 不能解决我的问题。我只想使用 concurrent.futures 模块。


submit() 超时是用来做什么的? ThreadPoolExecutor 将提交的项放入队列中,这意味着 submit() 不是真正的阻塞操作。只有当队列已满并且默认队列无限制时才会发生阻塞。 - dhke
是的,这个例子非常简单。我已经完成了更详细的帖子。 - Samuel Dauzon
这与你的代码不符。即使有几千个项目,submit() 应该是几乎瞬间完成的。submit() 只是安排一个任务以供(稍后)执行,它不会等待任务完成。在这段代码中没有任何东西应该让 submit() 花费 30 秒以上的时间。 - dhke
是的,我同意你的观点。你能想象 Action.define_name() 方法需要 30 秒以上的时间吗?我不能公开我们公司的真实代码,所以我只发布了一个简单的使用案例。 - Samuel Dauzon
1
在这种情况下,您希望中断正在运行的线程,而不是等待其提交。submit()返回一个具有超时的wait()方法的Future对象。您可能可以使用它。但更优雅的做法是编写工作代码,使其在达到超时时自动停止。通常直接杀死一个线程并不是一个好主意。 - dhke
可能是如何在Python中终止线程?的重复问题。 - dhke
1个回答

1
如果您真的想要使用超时异步执行,您可以将您的future包装在另一个future中,以便最后一个可以等待主要future,并且整个过程将是非阻塞的。像这样:
executor.submit(lambda: executor.submit(func, arg).result(timeout=50))

但这相当粗糙和低效

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接