V2EX › Python
python3.7 中的 async/await 以及 asyncio 问题
waibunleung · 2019-07-16 23:36:22 +08:00 · 4196 次点击
这是一个创建于 499 天前的主题,其中的信息可能已经有所发展或是发生改变。
有一段代码:
import asyncio
async def crawl_page(url):
print('crawling {}'.format(url))
sleep_time = int(url.split('_')[-1])
await asyncio.sleep(sleep_time)
print('OK {}'.format(url))
async def main(urls):
tasks = [asyncio.create_task(crawl_page(url)) for url in urls]
for task in tasks:
await task
%time asyncio.run(main(['url_1', 'url_2', 'url_3', 'url_4']))
########## 输出 ##########
crawling url_1
crawling url_2
crawling url_3
crawling url_4
OK url_1
OK url_2
OK url_3
OK url_4
Wall time: 3.99 s
我想问在 main 函数中的 for 循环处,原意是等待所有任务结束。但是遇到第一个 await 时不会直接跳出整个 for 循环吗?还是说只是会跳过当前的一轮循环?还是说 for 循环对于 await 其实有特别的处理对待?
我也知道这个和 python 的事件循环有关系,但是在网上找了不少资料都没有很能说清楚个大概的,希望 v 友们能给我解个惑,python 的事件循环是怎么样的?
第 1 条附言 · 2019-07-17 11:07:32 +08:00
我又换了一段代码:
```python
import asyncio
import time
async def crawl_page(url):
print('crawling {}'.format(url))
sleep_time = int(url.split('_')[-1])
await asyncio.sleep(sleep_time)
print('OK {}'.format(url))
async def main(urls):
tasks = [asyncio.create_task(crawl_page(url)) for url in urls]
# for task in tasks:
# await task
await tasks[2]
await tasks[1]
await tasks[0]
await tasks[3]
start = time.time()
asyncio.run(main(['url_1', 'url_2', 'url_4', 'url_3']))
end = time.time()
print('wall time:'+ str(end - start))
########## output ###########
crawling url_1
crawling url_2
crawling url_4
crawling url_3
OK url_1
OK url_2
OK url_3
OK url_4
wall time:4.005656003952026
```
大家可以仔细看看,url 的顺序我是调换了一下的。其实和 for 循环没有太大关系
第 2 条附言 · 2019-07-17 11:22:43 +08:00
import asyncio
import time
async def crawl_page(url):
print('crawling {}'.format(url))
sleep_time = int(url.split('_')[-1])
await asyncio.sleep(sleep_time)
print('OK {}'.format(url))
async def main(urls):
tasks = [asyncio.create_task(crawl_page(url)) for url in urls]
# for task in tasks:
# await task
await tasks[2]
print('will print after tasks[2] awaited?')
await tasks[1]
await tasks[0]
print('will print after tasks[0] awaited?')
await tasks[3]
start = time.time()
asyncio.run(main(['url_1', 'url_2', 'url_4', 'url_3']))
end = time.time()
print('wall time:'+ str(end - start))
###### output #######
crawling url_1
crawling url_2
crawling url_4
crawling url_3
OK url_1
OK url_2
OK url_3
OK url_4
will print after tasks[2] awaited?
will print after tasks[0] awaited?
wall time:4.002974987030029
有没有人能解释一下这段代码的运行逻辑?