任何 concurrent.futures 超时实际工作?

wim*_*wim 7 python timeout multiprocessing concurrent.futures

试图以便宜的方式编写基于进程的超时(同步),如下所示:

from concurrent.futures import ProcessPoolExecutor

def call_with_timeout(func, *args, timeout=3):
    with ProcessPoolExecutor(max_workers=1) as pool:
        future = pool.submit(func, *args)
        result = future.result(timeout=timeout)
Run Code Online (Sandbox Code Playgroud)

但似乎timeout传递给future.result的参数并没有像宣传的那样真正起作用。

>>> t0 = time.time()
... call_with_timeout(time.sleep, 2, timeout=3)
... delta = time.time() - t0
... print('wall time:', delta)
wall time: 2.016767978668213
Run Code Online (Sandbox Code Playgroud)

好的。

>>> t0 = time.time()
... call_with_timeout(time.sleep, 5, timeout=3)
... delta = time.time() - t0
... print('wall time:', delta)
# TimeoutError
Run Code Online (Sandbox Code Playgroud)

不正常 - 5 秒后解锁,而不是 3 秒。

相关问题显示了如何使用线程池或使用信号来做到这一点。如何在n秒后使提交到池的进程超时,而不使用任何多处理的 _private API?硬杀没问题,不需要要求干净关闭。

nox*_*fox 6

你可能想看看pebble

ProcessPool旨在解决这个确切的问题:启用超时和取消正在运行的任务,而无需关闭整个池。

当 future 超时或被取消时,worker 实际上被终止,有效地停止了调度函数的执行。

暂停:

pool = pebble.ProcessPool(max_workers=1)
future = pool.schedule(func, args=args, timeout=1)
try:
    future.result()
except TimeoutError:
    print("Timeout")
Run Code Online (Sandbox Code Playgroud)

例子:

def call_with_timeout(func, *args, timeout=3):
    pool = pebble.ProcessPool(max_workers=1)
    with pool:
        future = pool.schedule(func, args=args, timeout=timeout)
        return future.result()
Run Code Online (Sandbox Code Playgroud)

  • 正是因为这个,我才建造了 `pebble`。stdlib 池实现 `concurrent.futures` 和 `multiprocessing` 都有些过于乐观了。 (2认同)
  • 啊,我没想到你是鹅卵石的作者。感谢您的工作! (2认同)