python的协程

协程:

1:是一种线程内部的任务调度机制,通过事件循环实现任务的挂起与恢复执行

本质就是一个先处理,遇到IO操作时,不让CPU等待,把CPU交给其他任务

注意1:

协程不是操作系统提供的,CPU并不能看见协程

操作系统并不知道协程的存在

协程就是程序员用代码设计出来的任务切换机制

注意2:

协程一定是发生在线程里的

协程并不是在线程之间切换

而是线程内部多个任务在做切换

本质就是一个线程里,写了很多任务,由事件循环统一调度

注意3:

当任务遇到IO操作时:任务会被挂起

当IO操作完成之后,任务会恢复执行

注意4:

协程依赖(事件循环)

注意5:

协程的目标就是尽可能减少线程之间的切换

协程函数:(coroutine Function)使用async关键字修饰的函数,就是协程函数

协程对象:(coroutine Object)调用协程对象就会得到协程对象

注意:调用协程函数,并不会执行协程函数的代码

协程对象只能调用一次之后自动销毁

import asyncio

async def work():

print(f'开始工作')

print(f'正在工作')

print(f'工作结束')

return f'结束'

#通过协程函数调用得到协程对象

coroutine_obj = work()

print(coroutine_obj)

#将协程对象交给asyncio.run(),asyncio.run()会把协程对象包装成一个任务交给事件循环来执行

res = asyncio.run(coroutine_obj)

print(res)

await:

1:挂起:await会暂停当前的协程执行

2:等待:遇到await关键字,事件循环会立刻安排await之后的对象去执行并且等到该对象执行完毕

第一种情况:如果等待对象中的代码没有包含IO,此时事件循环是拿不到CPU控制权的,无法调度循环中的其他事务,不会发生任务切换

第二种情况:如果等待对象中包含IO,那么CPU的控制权就交给了事件循环,事件循环会安排执行其他任务(有的情况下)

3:恢复当await后的对象执行完毕之后,事件循环会立刻恢复之间被挂起的协程,该协程会从当前挂起的位置继续执行,并拿到返回值

await之后只能写可等待对象,协程对象,Future对象,Task对象

事件循环将任务交给CPU执行,如果看到了wait关键字就会把任务挂起,从而执行后续代码

事件循环是拿不到CPU控制权的,无法调度循环中的其他事物,不会发生任务切换

import asyncio

import time

async def work(n,delay):

print(f'{n}开始工作')

print(f'{n}正在工作')

await asyncio.sleep(delay)

print(f'{n}工作结束')

return f'{n}结束'

async def main():

print('main开始工作')

start = time.time()

res1 = await asyncio.gather(work(1,2),work(2,2),work(3,3))

print(res1)

print('main结束',time.time()-start)

return 'main结束'

res = asyncio.run(main())

print(res)

import asyncio

import time

async def work(n,delay):

print(f'{n}开始工作')

print(f'{n}正在工作')

await asyncio.sleep(delay)

print(f'{n}工作结束')

return f'{n}结束'

async def main():

print('main开始工作')

start = time.time()

res1 = await work(1,2)

print(res1)

res2 = await work(2, 2)

print(res2)

res3 = await work(3, 2)

print(res3)

print('main结束',time.time()-start)

return 'main结束'

res = asyncio.run(main())

print(res)

传统图片下载

图片是一张一张下载的,当图片没有下载完成,后一张图片就不能开始下载,就属于典型的同步下载

import requests

def download(url):

print()

response = requests.get(url)

with open(url-10:,'wb') as file:

file.write(response.content)

print('')

def main():

url_list = [

"https://twm.autohome.com.cn/cjh.autoimg.com/chejiahaodfs/g28/M06/C6/8C/752x0_q100_autohomecar__ChwFkmGNL_yAL9MoACMaRfUnzK4335.png?text/5bCP5Yaw5b-D6K-06L2m/fontSize/13"

]

for url in url_list:

download(url)

main()

协程图片下载

asyncio.gather

import aiohttp

import asyncio

async def download(session,url):

print()

response = await session.get(url)

content = await response.read()

with open(url-11:,'wb') as file:

file.write(response.content)

print('')

await response.release()

async def main():

url_list = [

"https://puui.qpic.cn/vpic_cover/l351257a0h4/l351257a0h4_1683069032_vt.jpg/720"

]

session = aiohttp.ClientSession()

coroutine_list = download(session,url) for url in url_list

await asyncio.gather(*coroutine_list)

await session.close()

asyncio.run(main())

asyncio.run()

1:创建了一个事件循环

2:将收到的协程对象,包装成一个任务,交给事件循环

3:启动事件循环

相关推荐
Warson_L8 小时前
Python `Annotated` 与 LangGraph Reducer 学习笔记
python
韩师傅8 小时前
海天线算法的前世今生
python·计算机视觉
韩师傅8 小时前
当你的甲方设备过烂,要如何快速出效果?
python·计算机视觉
Warson_L8 小时前
LangGraph的MessageState and HumanMessage
python
韩师傅8 小时前
当你的甲方吐槽天空不够蓝,你应该如何应对
python·计算机视觉
Warson_L9 小时前
python的类&继承
python
Warson_L9 小时前
类型标注/type annotation
python
ThreeS11 小时前
手搓MiniVLA全实战教程-一步一步用pytorch解释原理与思路
人工智能·python
金銀銅鐵13 小时前
[Python] 模 n 乘法的逆元计算器
python·数学·游戏