【发布时间】:2022-03-01 16:35:29
【问题描述】:
我有上传和下载文件的同步方法(以sync_wait方法为代表)。我想以一种永远同时并行执行上传器和下载器的方式异步且无休止地执行此操作。我是这样实现的:
运行此代码:
import time, asyncio
from functools import wraps, partial
# https://stackoverflow.com/a/50450553/3026886
def to_async(func):
@wraps(func)
async def run(*args, **kwargs):
return await asyncio.get_event_loop().run_in_executor(None, partial(func, *args, **kwargs))
return run
@to_async
def sync_wait(msg):
time.sleep(msg)
async def producer(n, queue):
while True:
msg = .2
await sync_wait(msg)
print(f'{n}p')
await queue.put(msg)
async def consumer(n, queue):
while True:
msg = await queue.get()
print(f'{n}c')
await sync_wait(msg)
async def main():
queue = queue = asyncio.Queue(10)
producers = [producer(n, queue) for n in range(2)]
consumers = [consumer(n, queue) for n in range(4)]
await asyncio.gather(*(producers + consumers), return_exceptions=True)
if __name__ == "__main__":
asyncio.run(main())
打印此输出:
1p
0p
0c
1c
1p
2c
0p
3c
1p
2c
0p
1c
1p
0c
0p
3c
1p
2c
0p
3c
1p
0c
0p
3c
...
这是有道理的,因为我有 2 个生产者和 4 个消费者与我的队列交互。我的老板告诉我我不需要 to_async 装饰器。但是在从sync_wait definiton 中只删除了装饰器之后,我根本没有打印出来。我该如何解释这种新行为?
【问题讨论】:
-
如果你只删除
sync_wait而不是await,事情应该会崩溃并出现明显的错误。 -
我只从
sync_wait中删除了装饰器,这意味着我继续使用sync_wait,但在其定义之上没有@to_async。没有抛出错误
标签: python-asyncio