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

相关推荐
我找到地球的支点啦18 分钟前
Matlab系列(009) 一CRC循环冗余校验详解
开发语言·数据结构·算法·matlab·信息与通信
维基框架19 分钟前
WIKI 知识库 v1.1.1 正式发布
人工智能·python
予昊21 分钟前
从零实现“在线五子棋对战“:WebSocket 实时通信 + 段位匹配
java·开发语言·网络·websocket
weixin_461408581 小时前
Mybatis-flex小记
java·开发语言·mybatis
青梅味猪大肠2 小时前
【深入浅出C++】为什么虚表指针可以解决菱形继承
开发语言·c++
潘潘的嵌入式日记2 小时前
I²C 从机接收总被覆盖?双缓冲要在 STOP 时交接
c语言·开发语言·单片机
Lhan.zzZ3 小时前
QML 组件库:VS2022 + Qt 静态库方案
开发语言·c++·qt·visual studio
敲代码的嘎仔3 小时前
28届后端开发-海康威视日常实习一面(已OC)
java·开发语言·后端·面试·海康威视·实习·大厂
谢白羽4 小时前
SGLang的AWQ量化笔记
笔记·python·sglang
sakiko_4 小时前
OC基础语法(与Swift对比)-1
开发语言·ios·objective-c·swift