看到吐血 (´ཀ`」 ∠)
import asyncio
import time
async def a():
print("欢迎使用 a !")
await asyncio.sleep(1)
print("欢迎回到 a !")
async def b():
print("欢迎来到 b !")
await asyncio.sleep(2)
print("欢迎回到 b !")
async def main():
task1 = asyncio.create_task(a())
task2 = asyncio.create_task(b())
print("准备开始")
await task1
print("task1 结束")
await task2
print("task2 结束")
if __name__ == "__main__":
start = time.perf_counter()
asyncio.run(main())
print('花费 {} s'.format(time.perf_counter() - start))
上面的代码也可以这样写,将15到21行换成一行await asyncio.gather(a(), b())
也能实现类似的效果,await asyncio.gather 会并发运行传入的可等待对象(Coroutine、Task、Future)。
import asyncio
import time
async def a():
print("欢迎使用 a !")
await asyncio.sleep(1)
print("欢迎回到 a !")
async def b():
print("欢迎来到 b !")
await asyncio.sleep(2)
print("欢迎回到 b !")
async def main():
await asyncio.gather(a(), b())
if __name__ == "__main__":
start = time.perf_counter()
asyncio.run(main())
print('花费 {} s'.format(time.perf_counter() - start))
"""
- 简单爬虫模拟
- 这里用异步接口写了个同步代码
"""
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):
for url in urls:
await crawl_page(url) # await会将程序阻塞在这里,进入被调用的协程函数,执行完毕后再继续
start = time.perf_counter()
# pip install nest-asyncio
asyncio.run(main(['url_1', 'url_2'])) # 协程接口
print("Cost {} s".format(time.perf_counter() - start))
# 异步实现
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
# 14、15行也可以换成这一行await asyncio.gather(*tasks)
# *tasks 解包列表,将列表变成了函数的参数,与之对应的是,** dict 将字典变成了函数的参数
start = time.perf_counter()
asyncio.run(main(['url_1', 'url_2']))
print("Cost {} s".format(time.perf_counter() - start))
# 极客时间:Python核心技术与实战
import asyncio
import random
import time
async def consumer(queue, id):
"""消费者"""
while True:
val = await queue.get()
print('{} get a val : {}'.format(id, val))
await asyncio.sleep(1)
async def producer(queue, id):
"""生产者"""
for _ in range(5):
val = random.randint(1, 10)
await queue.put(val)
print('{} put a val: {}'.format(id, val))
await asyncio.sleep(1)
async def main():
queue = asyncio.Queue()
consumer_1 = asyncio.create_task(consumer(queue, 'consumer_1'))
consumer_2 = asyncio.create_task(consumer(queue, 'consumer_2'))
producer_1 = asyncio.create_task(producer(queue, 'producer_1'))
producer_2 = asyncio.create_task(producer(queue, 'producer_2'))
await asyncio.sleep(10)
# cancel掉执行之间过长的consumer_1、consumer_2,while True
consumer_1.cancel()
consumer_2.cancel()
# return_exceptions 设为True,不让异常throw到执行层,影响后续任务的执行
await asyncio.gather(consumer_1, consumer_2, producer_1, producer_2, return_exceptions=True)
if __name__ == "__main__":
start = time.perf_counter()
asyncio.run(main())
print("Cost {} s".format(time.perf_counter() - start))
# 输出结果
producer_1 put a val: 7
producer_2 put a val: 4
consumer_1 get a val : 7
consumer_2 get a val : 4
producer_1 put a val: 6
producer_2 put a val: 1
consumer_2 get a val : 6
consumer_1 get a val : 1
producer_1 put a val: 8
producer_2 put a val: 1
consumer_1 get a val : 8
consumer_2 get a val : 1
producer_1 put a val: 6
producer_2 put a val: 4
consumer_2 get a val : 6
consumer_1 get a val : 4
producer_1 put a val: 7
producer_2 put a val: 8
consumer_1 get a val : 7
consumer_2 get a val : 8
Cost 10.0093015 s