热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Python中concurrent.futures超时机制的有效性探讨

本文探讨了Python中使用concurrent.futures模块实现进程超时的有效性,并提供了一种更可靠的解决方案。

尝试通过简单的方法实现基于进程的同步超时,代码示例如下:

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("任务超时")

推荐阅读
author-avatar
没搜摸索摸索_685
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有