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:启动事件循环

相关推荐
默_笙16 小时前
🍙 给每个请求过安检:FastAPI 是怎么把校验写进类型注解的
python
小羊没烦恼!16 小时前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
qq_4260039616 小时前
启动playwright录制codegen生成自动化测试脚本
python·自动化
虎头金猫16 小时前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
长沙三为智能科技17 小时前
家政小程序开发从0到上线:五阶段交付流程与验收清单
python
伞伞悦读17 小时前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
只睡四小时18 小时前
Canvas 弹道联机实战:700 行 + 固定时间步长
python·websocket·html5·游戏开发·canvas
C语言小火车18 小时前
C/C++ 为什么需要编译器?
开发语言·c++
奇思妙想聪明勤奋的小羊18 小时前
DeepAgents第5章:子Agent 与上下文隔离—让 Agent学会委派
人工智能·python·学习·语言模型
lpfasd12319 小时前
2026年第38周GitHub趋势周报
python·科技·github