协程,又称微线程。协程的作用是在执行函数A时可以随时中断去执行函数B,然后中断函数B继续执行函数A(可以自由切换)。但这一过程并不是函数调用,这一整个过程看似像多线程,但是协程仅在一个线程执行。
简单来讲,协程就是程序在碰到阻塞状态时能够选择性地切换到其他任务上。关于程序阻塞状态,一般程序进行IO操作时,线程会处入阻塞状态。在爬虫中,requests.get()也会使程序处入阻塞状态。
python中实现异步协程需要导入asyncio库。
下面我们将通过实例了解协程以及python中协程的基本实现。
import asyncio
import time
async def test_1():
print('1,点赞')
time.sleep(2)
print('1,点赞')
async def test_2():
print('2,收藏')
time.sleep(3)
print('2,收藏')
async def test_3():
print('3,分享')
time.sleep(4)
print('3,分享')
if __name__ == '__main__':
t1 = test_1()
t2 = test_2()
t3 = test_3()
tasks = [t1,t2,t3]
time1 = time.time()
asyncio.run(asyncio.wait(tasks))
time2 = time.time()
print('耗时:',time2-time1)
运行结果如下:
利用async定义函数,t1=test_1()等作用为将函数定义为异步协程函数,而此函数执行得到的是一个协程对象。tasks=[t1,t2,t3]表示一次性启动多个任务(协程),我们发现程序睡眠9秒,实际耗时9秒多一点点,说明在异步中执行time.sleep()等同步操作会中断异步。
将上述程序进行修改,做到异步协程:
import asyncio
import time
async def test_1():
print('1,点赞')
#time.sleep(2)
await asyncio.sleep(2)
print('1,点赞')
async def test_2():
print('2,收藏')
#time.sleep(3)
await asyncio.sleep(3)
print('2,收藏')
async def test_3():
print('3,分享')
#time.sleep(4)
await asyncio.sleep(4)
print('3,分享')
if __name__ == '__main__':
t1 = test_1()
t2 = test_2()
t3 = test_3()
tasks = [t1,t2,t3]
time1 = time.time()
asyncio.run(asyncio.wait(tasks))
time2 = time.time()
print('耗时:',time2-time1)
await asyncio.sleep(2)等表示这一协程执行到这一步进行休眠,就会在这一线程中就行其他线程,从而减少运行时间,提高效率。代码运行结果如下:
上面带大家了解了协程的基本内容,下面介绍协程在python中的基本实现与主要的写法。
import asyncio
import time
async def test_1():
print('1,点赞')
await asyncio.sleep(2)
print('1,点赞')
async def test_2():
print('2,收藏')
await asyncio.sleep(3)
print('2,收藏')
async def test_3():
print('3,分享')
await asyncio.sleep(4)
print('3,分享')
async def main():
tasks = [test_1(),test_2(),test_3()]
await asyncio.wait(tasks)
if __name__ == '__main__':
time1 = time.time()
asyncio.run(main())
time2 = time.time()
print('耗时:',time2-time1)
以上就是协程的主要写法,将多个协程封装为main函数,在执行main函数实现异步协程。
执行结果如下:
解决warning的方法就是将tasks=[test_1(),test_2(),test_3()]改为tasks=[asyncio.create_task(test_1()),asyncio.create_task(test_2()),asyncio.create_task(test_3())]
因此可以将上述代码改为:
import asyncio
import time
async def test_1():
print('1,点赞')
await asyncio.sleep(2)
print('1,点赞')
async def test_2():
print('2,收藏')
await asyncio.sleep(3)
print('2,收藏')
async def test_3():
print('3,分享')
await asyncio.sleep(4)
print('3,分享')
async def main():
tasks = [asyncio.create_task(test_1()),asyncio.create_task(test_2()),asyncio.create_task(test_3())]
await asyncio.wait(tasks)
if __name__ == '__main__':
time1 = time.time()
asyncio.run(main())
time2 = time.time()
print('耗时:',time2-time1)
执行结果如下: