协程的介绍:
- 协程:在单线程内实现并发
- 核心原理:
- 用一个超级循环(其实就是while true)循环
- 配合IO多路复用原理(IO时CPU可以干其他事情)
asyncio的使用:
import asyncio
loop = asyncio.get_event_loop()
async def myfunc(url):
await get_url(url)
tasks = [loop.create_task(myfunc(url)) for url in urls]
loop.run_until_complete(asyncio.wait(tasks))
import asyncio
async def main():
print('Hello ...')
await asyncio.sleep(1)
print('... World!')
asyncio.run(main())
协程的案例对比:
import asyncio
import time
async def wait(num, data):
await asyncio.sleep(num)
return data
"""
执行main_1()可发现,程序在sleep时并没有直接进行下一步,而是等第一个sleep结束后才继续执行
"""
async def main_1():
start = time.time()
res1 = await wait(1, "hello...")
print(res1)
res2 = await wait(2, "world!")
print(res2)
end = time.time()
print("time:", end-start)
asyncio.run(main_1())
"""
使用create_task()方法创建task,将其task添加进even_loop,使得task1在等待时即可执行task2
"""
async def main_2():
task1 = asyncio.create_task(wait(1, "hello..."))
task2 = asyncio.create_task(wait(2, "world!"))
start = time.time()
res1 = await task1
print(res1)
res2 = task2
print(res2)
end = time.time()
print("time:", end-start)
"""
当任务较多时,可使用gather()方法,该方法可以将每个协程变成task
"""
async def main_3():
start = time.time()
res = await asyncio.gather(
wait(1, "hello..."),
wait(2, "world!")
)
print(res)
end = time.time()
print("time:", end-start)
通过信号量控制协程数:
import asyncio
semaphore = asyncio.Semaphore(10)
async with semaphore:
...