【发布时间】:2021-12-28 07:35:23
【问题描述】:
我想编写一个包装器,用于在 asyncio 中调用 CPU 要求高的函数。
我希望它像这样使用:
@cpu_bound
def fact(x: int):
res: int = 1
while x != 1:
res *= x
x -= 1
return res
async def foo(x: int):
res = await fact(x)
...
起初,我写道:
def cpu_bound(func: Callable[P, R]) -> Callable[P, Awaitable[R]]:
@functools.wraps(func)
async def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
executor = get_executor() # This is a part where I implemented myself.
return await loop.run_in_executor(
executor, functools.partial(func, *args, **kwargs)
)
return wrapper
但是,我遇到了酸洗问题。
Traceback(最近一次调用最后一次):文件 "C:\Users\Lenovo\AppData\Local\Programs\Python\Python39\lib\multiprocessing\queues.py", 第 245 行,在 _feed 中 obj = _ForkingPickler.dumps(obj) 文件“C:\Users\Lenovo\AppData\Local\Programs\Python\Python39\lib\multiprocessing\reduction.py”, 第 51 行,在转储中 cls(buf, 协议).dump(obj) _pickle.PicklingError: Can't pickle
: it's not the same object as main.fact
也许原始函数和包装函数不具有相同的id 是问题所在?
那么,有没有办法编写这样的包装器?
我知道我可以使用loop.run_in_executor,但是拥有这样的包装器会很有帮助。
【问题讨论】:
-
也许你必须像正常功能一样运行它
res = await cpu_bound(fact)(x)
标签: python multiprocessing python-asyncio pickle wrapper