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

相关推荐
Yolanda942 小时前
【人工智能】AI问答助手项目
人工智能·python
武超杰2 小时前
Spring Cloud Alibaba Nacos 进阶:配置隔离、集群、持久化与开机自启
java·开发语言
qq_206901392 小时前
如何在 WordPress 中通过邮箱获取用户 ID(PHP 实现)
jvm·数据库·python
Rabitebla2 小时前
C++类和对象(中):默认函数 + 运算符重载 + 日期类实现完整笔记
java·开发语言·javascript
亚林瓜子2 小时前
AWS Glue Python Shell中获取外网ip
python·tcp/ip·http·shell·aws·vpc·glue
Bat U2 小时前
JavaEE|多线程(一)
java·服务器·开发语言
逻辑驱动的ken2 小时前
Java高频面试考点场景题05
java·开发语言·深度学习·求职招聘·春招
Royzst2 小时前
String方法
java·开发语言
进击的松鼠2 小时前
从对话到动作:用 Function Calling 把 LLM 接到真实 API(含流程拆解)
python·llm·agent