我正在使用Rollcio和ProcessPoolExecutor来运行一段像这样的阻塞代码:
result = await loop.run_in_executor(pool, long_running_function)
我不希望long_running_function持续时间超过2秒,并且我无法在其中进行适当的超时处理,因为该函数来自第三方库。
我有哪些选择?
1.向long_running_function?
https://pypi.org/project/timeout-decorator/添加超时指示器
1.使用Pebble https://pebble.readthedocs.io/en/latest/#pools-and-asyncio
哪一个是最好的选择?
此q非常接近Timeout handling while using run_in_executor and asyncio,对此没有报告解决方法。
已经好几年了有没有一个变通办法?
1条答案
按热度按时间cgfeq70w1#
如果您无法控制目标长时间运行的代码,这是很棘手的。但是,如果是Python,那么应该可以通过装饰它来修改被调用的函数(即有一个对另一个函数的 Package 器调用)-问题是, Package 器不能在另一个函数内部添加超时检查代码。而且他们不能在超时后“杀死”它,即使它在另一个线程中被调用。
但是,由于您正在其他进程中运行:与线程不同,子进程 * 可以 * 从另一个进程中的外部线程被杀死。* 但是 * 你正在运行一个并发的.futures兼容的执行器:简单地杀死目标进程会杀死其中一个工作进程,如果你这么做的话,普通的stdlib的
ProcessPoolExecutor
会被破坏--可能会使整个执行程序崩溃。如果Pebble的文档说他们的一个专门化就是在执行程序中运行时允许超时-那么,这就是要走的路。
不过,在不重复Pebble的情况下,我会这样做:有一个目标控制 Package 器函数,将由执行器调用:它将创建单个工作进程,并在需要时通过终止其工作进程来处理超时。(它甚至可以处理通过队列发送的控制事件)。
或者,为了减少每个worker多一个进程的开销,我可能会创建一个专门的Executor来处理超时,使用主进程循环本身(这可能是Pebble已经做的)。
但是,是的,为ProcessPoolExecutor任务设置一个“超时”可能是Python在未来版本中可以看到的一个增强--人们可以在该语言的官方主题https://discuss.python.org/c/ideas/6上为它“投票”
(It在这里编写这样的控制代码是可能的,但是考虑到所有与子进程相关的边缘情况,将重新发明已经存在于stdlib和Pebble上的良好润滑的轮子,并且可能不适合所有情况-尽管它肯定适用于简单情况)