gpt4 book ai didi

python - 具有多处理的超时装饰器类会产生酸洗错误

转载 作者:太空宇宙 更新时间:2023-11-04 02:27:48 25 4
gpt4 key购买 nike

所以在 Windows 上 signalthread approahc 通常是坏主意/不适用于函数超时。

我编写了以下超时代码,它会抛出一个 timeout exception来自 multiprocessing当代码花了很长时间。这正是我想要的。

 def timeout(timeout, func, *arg):
with Pool(processes=1) as pool:
result = pool.apply_async(func, (*arg,))
return result.get(timeout=timeout)

我现在正在尝试将它变成装饰器样式,以便我可以将它添加到范围广泛的函数中,尤其是那些调用外部服务并且我无法控制代码或持续时间的函数。我目前的尝试如下:

class TimeWrapper(object):

def __init__(self, timeout=10):
"""Timing decorator"""
self.timeout = timeout

def __call__(self, f):
def wrapped_f(*args):
with Pool(processes=1) as pool:
result = pool.apply_async(f, (*args,))
return result.get(timeout=self.timeout)

return wrapped_f

它给出了酸洗错误:

@TimeWrapper(7)
def func2(x, y):
time.sleep(5)
return x*y

File "C:\Users\rmenk\AppData\Local\Continuum\anaconda3\lib\multiprocessing\reduction.py", line 51, in dumps
cls(buf, protocol).dump(obj)
_pickle.PicklingError: Can't pickle <function func2 at 0x000000770C8E4730>: it's not the same object as __main__.func2

我怀疑这是由于多处理和装饰器没有很好地发挥作用,但我实际上不知道如何让它们发挥得很好。关于如何解决此问题的任何想法?

PS:我在这个网站和其他地方做了一些广泛的研究,但没有找到任何有效的答案,无论是使用 pebble、线程、作为函数装饰器还是其他方式。如果您知道可以在 Windows 和 Python 3.5 上运行的解决方案,我会非常乐意使用它。

最佳答案

您要实现的目标在 Windows 中特别麻烦。核心问题是当你装饰一个函数时,你遮蔽了它。这恰好在 UNIX 中工作得很好,因为它使用了 fork。创建新流程的策略。

但在 Windows 中,新进程将是一个空白进程,其中将启动一个全新的 Python 解释器并加载您的模块。当模块加载时,装饰器隐藏了真正的函数,使得 pickle 协议(protocol)很难找到。

唯一正确的方法是依靠在装饰期间设置的蹦床功能。您可以查看如何在 pebble 上完成但是,只要您不是为了练习而这样做,我建议您直接使用 pebble,因为它已经提供了您正在寻找的东西。

from pebble import concurrent

@concurrent.process(timeout=60)
def my_function(var, keyvar=0):
return var + keyvar

future = my_function(1, keyvar=2)
future.result()

关于python - 具有多处理的超时装饰器类会产生酸洗错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49936735/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com