Python 3.5异步用于阻止ioloop [英] Python 3.5 async for blocks the ioloop
问题描述
我有一个带有两个处理程序的简单aiohttp服务器。
第一个在 async for
循环中进行一些计算。第二个只是返回文本响应。 not_so_long_operation
返回第30个斐波那契数,其递归实现最慢,大约需要一秒钟的时间。
I have a simple aiohttp-server with two handlers.
First one does some computations in the async for
loop. Second one just returns text response. not_so_long_operation
returns 30-th fibonacci number with the slowest recursive implementation, which takes something about one second.
def not_so_long_operation():
return fib(30)
class arange:
def __init__(self, n):
self.n = n
self.i = 0
async def __aiter__(self):
return self
async def __anext__(self):
i = self.i
self.i += 1
if self.i <= self.n:
return i
else:
raise StopAsyncIteration
# GET /
async def index(request):
print('request!')
l = []
async for i in arange(20):
print(i)
l.append(not_so_long_operation())
return aiohttp.web.Response(text='%d\n' % l[0])
# GET /lol/
async def lol(request):
print('request!')
return aiohttp.web.Response(text='just respond\n')
当我尝试获取 /
然后是 / lol /
,它仅在第一个完成时才给出第二个响应。
我在做错什么,如何使索引处理程序在每次迭代时释放ioloop?
When I'm trying to fetch /
and then /lol/
, it gives me response for the second one only when the first one gets finished.
What am I doing wrong and how to make index handler release the ioloop on each iteration?
推荐答案
您的示例没有 yield点(等待
语句)以在任务之间进行切换。
异步迭代器允许在 __ aiter __
/ <$ c $中使用 await
c> __ anext __ ,但不要将其自动插入代码中。
Your example has no yield points (await
statements) for switching between tasks.
Asynchronous iterator allows to use await
inside __aiter__
/__anext__
but don't insert it automatically into your code.
说,
class arange:
def __init__(self, n):
self.n = n
self.i = 0
async def __aiter__(self):
return self
async def __anext__(self):
i = self.i
self.i += 1
if self.i <= self.n:
await asyncio.sleep(0) # insert yield point
return i
else:
raise StopAsyncIteration
应该按预期工作。
在实际应用中很可能不需要等待asyncio.sleep(0)
调用,因为您将等待数据库访问和类似的活动。
In real application most likely you don't need await asyncio.sleep(0)
calls because you will wait on database access and similar activities.
这篇关于Python 3.5异步用于阻止ioloop的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!