作者:没搜摸索摸索_685 | 来源:互联网 | 2024-12-14 23:21
尝试通过简单的方法实现基于进程的同步超时,代码示例如下:
from concurrent.futures import ProcessPoolExecutor
import time
def call_with_timeout(func, *args, timeout=3):
with ProcessPoolExecutor(max_workers=1) as pool:
future = pool.submit(func, *args)
try:
result = future.result(timeout=timeout)
return result
except TimeoutError:
print("任务超时")
理论上,传递给future.result()
的超时参数应该能够限制任务的执行时间,但实际上其效果并不理想。
>>> start_time = time.time()
>>> call_with_timeout(time.sleep, 2, timeout=3)
>>> elapsed_time = time.time() - start_time
>>> print('实际耗时:', elapsed_time)
实际耗时: 2.016767978668213
这看起来是正确的。
>>> start_time = time.time()
>>> call_with_timeout(time.sleep, 5, timeout=3)
>>> elapsed_time = time.time() - start_time
>>> print('实际耗时:', elapsed_time)
# 抛出TimeoutError
然而,这里的问题在于,尽管抛出了超时异常,但实际的执行时间仍然是5秒,而非预期的3秒。
针对这一问题,一些相关的解决方案建议使用线程池或信号处理来实现。但是,有没有一种方法可以在不使用多处理的私有API的情况下,在n秒后超时并终止进程?硬性终止进程是可以接受的,不一定需要优雅地关闭。
一个推荐的解决方案是使用pebble
库。该库的ProcessPool
设计旨在解决上述问题,即允许设置超时并取消正在运行的任务,而无需关闭整个进程池。当任务超时或被取消时,工作进程将被终止,从而停止执行预定的功能。
from pebble import ProcessPool
pool = ProcessPool(max_workers=1)
future = pool.schedule(func, args=args, timeout=1)
try:
result = future.result()
except TimeoutError:
print("任务超时")
具体实现如下:
def call_with_timeout(func, *args, timeout=3):
with ProcessPool(max_workers=1) as pool:
future = pool.schedule(func, args=args, timeout=timeout)
try:
return future.result()
except TimeoutError:
print("任务超时")