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

相关推荐
划水的code搬运工小李几秒前
下载CSDN到PDF
开发语言·pdf·swift
程序大视界2 分钟前
【Python系列课程】Pandas(六):数据读写——CSV与Excel文件操作
python·excel·pandas
不负岁月无痕4 分钟前
STL-- C++ stack_queue _priority_queue类 模拟实现
开发语言·c++
半个烧饼不加肉6 分钟前
JS 底层探究--上下文
开发语言·javascript·ecmascript
小满Autumn8 分钟前
依赖注入设计模式速查手册
开发语言·c#·wpf·mvvm·依赖注入
周末也要写八哥16 分钟前
浅谈:C++中cpp 14 ~ cpp 17
开发语言·c++·算法
不会C语言的男孩19 分钟前
C++ Primer 第13章:拷贝控制
开发语言·c++
z落落23 分钟前
C# 静态成员 vs 非静态成员(调用规则+内存特点)+只读和常量 const常量 / readonly / static readonly 三者终极区别
java·开发语言·c#
zhangfeng113324 分钟前
超算中心 高性能计算 slurm的linux版本 centos7,如何安装docker,如何安装torch2.4
linux·运维·服务器·开发语言·人工智能·机器学习·docker
weixin_4074438726 分钟前
OCR材料信息提取工具(附件中含代码和数据)
人工智能·python·计算机视觉·ocr