我正在使用 asyncio 和 ProcessPoolExecutor 来运行一段这样的阻塞代码:
result = await loop.run_in_executor(pool, long_running_function)
我不希望 long_running_function 持续超过 2 秒,并且我无法在其中进行适当的超时处理,因为该函数来自第三方库。
我有什么选择?
long_running_function?
添加超时装饰器 https://pypi.org/project/timeout-decorator/哪个是最好的选择?
这个 q 非常接近 使用 run_in_executor 和 asyncio 时的超时处理,但没有报告解决方法。
已经过去几年了。 有解决方法吗?
如果您无法控制目标长时间运行的代码,这会很棘手。但是,如果是 Python,则应该可以通过装饰来修改被调用的函数(即对另一个函数进行包装器调用) - 问题是,包装器无法在另一个函数内部添加超时检查代码。并且他们无法在超时后“杀死”它,即使它是在另一个线程中调用的。 但是,由于您正在其他进程中运行事物:与线程不同,子进程
可以从另一个进程中的外部线程中杀死。但是你正在运行一个concurrent.futures兼容的执行器:简单地杀死目标进程就会杀死一个worker,而普通的stdlib的ProcessPoolExecutor
如果你这样做的话就会被削弱——可能会导致整个执行器瘫痪。
如果 Pebble 的文档说他们的专业化之一正是允许在执行器中运行时超时 - 那么,这就是要走的路。不过,不用再重复 Pebble,我要做的就是:有一个由执行器调用的目标控制包装函数:它将创建一个工作进程,并在需要时通过终止其工作进程来处理超时。 (它甚至可以处理通过队列发送的控制事件)。
或者,为了减少每个工作进程一个额外进程的开销,我可能会创建一个专门的执行器来处理超时,使用主进程异步循环本身(这可能是 Pebble 已经做的)。
但是,是的,为 ProcessPoolExecutor 任务设置“超时”可能是 Python 在未来版本中可以看到的一项增强功能 - 人们可以在该语言的官方想法主题中“投票”它,网址为
https://discuss.python.org/ c/想法/6