昨天我刚学会了与python 3.5异步。
这就是我今天想要完成的事情。
import asyncio
import time
import requests
async def foo():
"""Some Long Running Taks"""
requests.get("http://stackoverflow.com/questions/41301031/asyncio-on-long-running-task")
print("foo")
async def bar():
"""Some Quick Task"""
print("bar")
while True:
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(foo(), bar()))
loop.close()
time.sleep(2)
#Expected output
"""
>>>bar
>>>bar
>>>bar
>>>bar
>>>bar
>>>foo
and so on
"""
这可以使用python async / await吗?
答案 0 :(得分:2)
您的代码中存在一些问题:
请求不支持asyncio,请改用aiohttp。
您的couroutines仅在循环运行时运行:仅在代码中调用loop.run_until_complete()
一次,并使用await
(或asycio.ensure_future()
安排许多(短期或长期)任务}或loop.create_task()
)。
以下是一个与您尝试的操作类似的示例:
# make sure to run `pip install aiohttp` first!!!
import asyncio
import aiohttp
async def slow_fetch(delay):
url = "http://httpbin.org/delay/{}".format(delay)
print("Getting ", url)
async with aiohttp.ClientSession() as session:
async with session.get(url) as resp:
text = await resp.text()
print("Got {}, {} chars".format(url, len(text)))
async def quick_loop():
print("enter quick_loop")
for i in range(10):
await asyncio.sleep(1)
print("quick_loop", i)
print("exit quick_loop")
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(
slow_fetch(3),
slow_fetch(4),
quick_loop(),
))
loop.close()
答案 1 :(得分:0)
你的time.sleep()
正在阻止;你需要使用asyncio.sleep()
。
为什么在loop
内运行while True
?
还要注意asyncio
只会帮助加速io-bound任务(例如从网上获取数据)。它不会帮助你加速cpu绑定的任务。为此,您需要threads或multiplrocessing。
看到您更新了问题,我的回答中有一个小更新:requests
也阻止了,asyncio
的效果不佳。 aiohttp
的功能类似,但与asyncio
答案 2 :(得分:0)
这是ensure_future
/ create_task
的更好方法:
使用装饰器
def async_wrap(func):
@wraps(func)
async def run(*args, loop=None, executor=None, **kwargs):
if loop is None:
loop = asyncio.get_event_loop()
pfunc = partial(func, *args, **kwargs)
return await loop.run_in_executor(executor, pfunc)
return run
现在,如果您有运行时间较长的功能(例如使用requests
的功能),则可以执行以下操作:
@async_wrap
def long_running_function():
return requests.get(_URL)