python -- 异步、asyncio

文章目录

  • 协程
    • 实现协成的方法
      • greenlet实现协程
      • yield 关键字
      • asyncio async & await(**重点**)
  • 协程的意义
  • 异步编程
    • 事件循环
    • 快速上手
    • await
    • Task对象
    • asyncio.Future对象
    • concurrent.futures.Future 对象

协程

协成不是操作系统提供的,是程序员人为创造的。

协成(Coroutine), 也可以被称为微线程,是一种用户态内的上下文切换技术,简而言之,其实就是通过一个线程实现代码块相互切换执行。

举个例子:

def func1():
    print(1)
    ...
    print(2)

def func2():
    print(3)
    ...
    print(4)

func1()
func2()

正常运行: 1 2 3 4
协程运行效果:1 3 2 4

实现协成的方法

  • greenlet, 早期模块。
  • yield 关键字
  • asyncio 装饰器(python3.4)
  • async、await(python3.7)[推荐,主讲]

greenlet实现协程

pip install greenlet

在这里插入图片描述
运行结果: 1 3 2 4

yield 关键字

def func1():
    yield 1
    yield from func2()
    yield 2

def func2():
    yield 3
    yield 4

f1 = func1()
for item in f1:
    print(item)

运行结果: 1 3 4 2

asyncio async & await(重点

  • 遇到IO阻塞自动切换
import asyncio

async def func1():
    print(1)
    await asyncio.sleep(2)
    print(2)

async def func2():
    print(3)
    print(4)

tasks = [
    asyncio.ensure_future( func1() ),
    asyncio.ensure_future( func2() ),
]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

先尝试运行理解,后面详细讲解

协程的意义

在一个线程中如果遇到IO等待时间,线程不会傻傻等待,利用空闲时间再去干点其他事。

案例:去下载三张图片(网络IO)

  • 普通三张图片(同步)
import requests

def download_img(url):
    print('开始下载:', url)
    # 发送请求
    response = requests.get(url)
    # 保存图片
    file_name = url.split('/')[-1]
    with open(file_name, mode='wb') as f:
        f.write(response.content)
        
if __name__ == '__main__':
    url_list = ['url1', 'url2', 'url3']
    for url in url_list:
        download_img(url)

结果:url1(下载,结束)–>url2(下载,结束)–>url3(下载,结束)

  • 协程方式(异步)
import asyncio
import aiohttp

async def download_img(session, url):
    print('开始下载:', url)
    # 发送请求
    async with session.get(url, verify_ssl=False) as response:
        content = await response.content.read()
        # 保存图片
        file_name = url.split('/')[-1]
        with open(file_name, mode='wb') as f:
            f.write(content)

async def main():
    async with aiohttp.client() as session:
        url_list = ['url1', 'url2', 'url3']
        tasks = [asyncio.create_task(download_img(session, url)) for url in url_list]
        await asyncio.wait(tasks)

if __name__ == '__main__':
    asyncio.run(main())

结果: 下载(url1, url2, url3) -同时下载->完成(url1, url2, url3)

协程是实现异步的一种方式!!!不是唯一方式。

异步编程

事件循环

理解成为一个死循环,去检测并执行某些代码。
在这里插入图片描述
以上描述的是以下代码:

# 去生成或获取一个时间循环
loop = asyncio.get_event_loop()
# 将任务放到“任务列表”
loop.run_until_complete(任务)

快速上手

协程函数,定义函数时,async def 函数名
协程对象,执行协程函数()得到的协程对象。

async def func():
	pass
result = func()

注意:执行协程函数对象,函数内部代码不会执行。

async def func():
	print('执行我吧')
result = func()

loop = asyncio.get_event_loop()
loop.run_until_complete(result)

# 或者 python3.7以上
asyncio.run(result)

await

await + 可等待的对象(协程对象、Future、Task对象–>IO等待)

import asyncio


async def func():
	print('执行我吧')
	response = await asyncio.sleep(2)
	print('结束:', response)

result = func()
asyncio.run(result)

结果:

执行我吧
结束: None

await 就是等待对象得到结果之后再继续向下走

Task对象

在事件循环中,添加多个任务

  • 示例1
# 示例1
import asyncio

async def func():
	print(1)
	response = await asyncio.sleep(2)
	print('2')
	return '结束func'

async def main():
	print('main开始')

	# 创建task对象
	task1 = asyncio.create_task(func())

	# 再次创建
	task2 = asyncio.create_task(func())

	print('main结束')

	re1 = await task1
	re2 = await task2
	print(re1, re2)

asyncio.run(main())

结果:

main开始
main结束
1
1
2
2
结束func 结束func
  • 示例2:
# 示例2
import asyncio

async def func():
	print(1)
	response = await asyncio.sleep(2)
	print('2')
	return '结束func'

async def main():
	print('main开始')

	# 创建task对象
	task_list = [asyncio.create_task(func())]

	print('main结束')

	done,pending = await asyncio.wait(task_list, timeout=2) # 最多等2秒
	print(done) # 已完成集合
	print(pending) # 未完成集合

asyncio.run(main())

asyncio.Future对象

Task 继承 Future,Task 对象内部await 结果的处理基于Future对象来的。

  • 示例1
import asyncio


async def main():
	# 获取当前循环
	loop = asyncio.get_running_loop()

	# 创建一个任务(Future对象),这个任务什么都不干
	fut = loop.create_future()

	# 等待任务最终结果(Future对象),没有结果则会一直等待下去
	await fut

asyncio.run(main())
  • 示例2
import asyncio

async def set_after(fut):
	await asyncio.sleep(2)
	fut.set_result('666')

async def main():
	# 获取当前循环
	loop = asyncio.get_running_loop()

	# 创建一个任务(Future对象),这个任务什么都不干
	fut = loop.create_future()

	# 创建一个任务(Task对象),绑定了set_after函数
	# fut.set_result('666')
	await loop.create_task(set_after(fut))

	# 等待Future对象获取最终结果,否则一直等待下去
	data = await fut
	print(data)

	# 等待任务最终结果(Future对象),没有结果则会一直等待下去
	await fut

asyncio.run(main())

concurrent.futures.Future 对象

使用线程池、进程池实现异步操作时用到的对象。

import time
from concurrent.futures import Future
from concurrent.futures.thread import ThreadPoolExecutor
from concurrent.futures.process import ProcessPoolExecutor

def func(value):
	time.sleep(1)
	print(value)
	return 1

# 创建线程池
pool = ThreadPoolExecutor(max_workers=5)

# 创建进程池
# pool = ThreadPoolExecutor(max_workers=5)

for i in range(10):
	fut = pool.submit(func, i)
	print(fut)

以后写代码可能多线程、进程和协程交叉使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/705253.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LLM-不要错过,教你如何快速且精准生成提示词?(总结Singapore首届GPT-4提示工程获奖者Sheila Teo博客)

文章目录 前置理论精炼介绍1. CO-STAR框架CO-STAR框架简单介绍CO-STAR简单示例 2. 创建系统提示【优化LLM问答丰富度】何为系统提示?系统提示示例 3. 使用分隔符分段提示【优化问答准度】分割符作特殊字符及CO-STAR示例分割符作XML标记 仅数据的CO-STAR实操前置分析…

如何用西语问候呢,柯桥零基础西班牙语培训

正式问候 在正式场合,如工作会议、正式介绍或第一次见面时,通常使用更为尊敬和礼貌的问候语。以下是一些例子: 1. Buenos das(早上好):从早上到中午使用。这是一个非常常见和礼貌的问候。 2. Buenas tardes(下午好):…

HTML静态网页成品作业(HTML+CSS)—— 节日母亲节介绍网页(5个页面)

🎉不定期分享源码,关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 🏷️本套采用HTMLCSS,未使用Javacsript代码,共有5个页面。 二、作品演示 三、代…

2024年3月电子学会青少年软件编程 中小学生Python编程等级考试二级真题解析(判断题)

2024年3月Python编程等级考试二级真题解析 判断题(共10题,每题2分,共20分) 26、元组中的元素可以是不同的数据类型 答案:对 考点分析:考查元元组相关知识,元组里面的元素是可以出现不同的数据…

流程设计的基本步骤

背景 公司为什么要流程,已经有专门章节进行阐述; 什么是流程,已经有专门章节进行专门阐述; 那么接下来这个章节讨论,流程设计的基本步骤,那么谁来设计流程呢,让一个部门的员工来设计一份流程…

30字以内免费翻译维吾尔语,汉维翻译工具推荐,维吾尔文字母OCR识别神器《维汉翻译通》App!

维吾尔文OCR文字识别 《维汉翻译通》App内置的OCR技术,能够快速识别图片中的文字和字母,无论是路标、菜单还是书籍,都能迅速转换为用户所需的语言,让语言障碍不再是问题。针对维吾尔语更是进行了专门的优化,即便是手写…

vue3+electron搭建桌面软件

vue3electron开发桌面软件 最近有个小项目, 客户希望像打开 网易云音乐 那么简单的运行起来系统. 前端用 Vue 会比较快一些, 因此决定使用 electron 结合 Vue3 的方式来完成该项目. 然而, 在实施过程中发现没有完整的博客能够记录从创建到打包的流程, 摸索一番之后, 随即梳理…

Android 14 系统启动流程 之 启动init进程、启动Zygote进程

Android 14 系统启动流程 之 启动init进程、启动Zygote进程 废话不多说,先上图,不清楚的可以在评论区留言。

C#下WinForm多语种切换

这是应一个网友要求写的,希望对你有所帮助。本文将介绍如何在一个WinForm应用程序中实现多语种切换。通过一个简单的示例,你将了解到如何使用资源文件管理不同语言的文本,并通过用户界面实现语言切换。 创建WinForm项目 打开Visual Studio&a…

ACL原理和基础配置

ACL(Access Control List,访问控制列表)是一种用于控制网络设备或操作系统上资源访问权限的方法。ACL能够基于规则和条件来允许或拒绝对资源的访问。 标准ACL(Standard ACL):基于源IP地址来进行流量过滤&a…

实现一个vue js小算法 选择不同的时间段 不交叉

以上图片选择了时间段 现在需要判断 当前选择的时间段 不能够是 有交叉的所以现在需要循环判断 //判断时间段是否重叠交叉 export function areIntervalsNonOverlapping(intervals:any) {// 辅助函数:将时间字符串转换为从当天午夜开始计算的分钟数function conver…

视频格式转换avi格式怎么弄?分享视频转换方法

视频格式转换avi格式怎么弄?AVI作为一种广泛支持的视频格式,能够在多种设备和播放器上顺畅播放,确保我们的视频内容能够无障碍地分享给朋友或上传至各大平台。其次,AVI格式通常具有较好的兼容性,能够避免格式转换过程中…

Coursera耶鲁大学金融课程:Financial Markets 笔记Week 01

Financial Markets 本文是学习 https://www.coursera.org/learn/financial-markets-global这门课的学习笔记 这门课的老师是耶鲁大学的Robert Shiller https://en.wikipedia.org/wiki/Robert_J._Shiller Robert James Shiller (born March 29, 1946)[4] is an American econ…

React+TS前台项目实战(七)-- 全局常用组件Select封装

文章目录 前言Select组件1. 功能分析2. 代码详细注释说明3. 使用方式4. 效果展示(1)鼠标移入效果(2)下拉框打开效果(3)回调输出 总结 前言 今天这篇主要讲全局select组件封装,可根据UI设计师要…

力扣148. 排序链表

给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。 示例 1: 输入:head [4,2,1,3] 输出:[1,2,3,4] 示例 2: 输入:head [-1,5,3,4,0] 输出:[-1,0,3,4,5] 示例 3&…

谷粒商城实战(036 k8s集群学习2-集群的安装)

Java项目《谷粒商城》架构师级Java项目实战,对标阿里P6-P7,全网最强 总时长 104:45:00 共408P 此文章包含第343p-第p345的内容 k8s 集群安装 kubectl --》命令行操作 要进入服务器 而且对一些不懂代码的产品经理和运维人员不太友好 所以我们使用可视化…

私域引流宝PHP源码 以及搭建教程

私域引流宝PHP源码 以及搭建教程

怎么防止源代码泄露?9种方法教会你!

怎么防止源代码泄露?首先要了解员工可以通过哪些方式将源代码传输出去! 物理方法: — 网线直连,即把网线从墙上插头拔下来,然后和一个非受控电脑直连; — winPE启动,通过光盘或U盘的winPE启动,甚…

夏日炎炎 水域守护:北斗守护安全防线——为生命撑起智能保护伞

随着夏季的来临,炎热的天气让许多人纷纷寻求水的清凉。清凉的河流与广阔的海域成为了不少人消暑降温的向往之地。然而,私自下河、下海的行为却暗藏着巨大的安全隐患,每年夏季溺水事故频发,给无数家庭带来不可挽回的悲痛。为有效遏…

高考志愿填报,如何分析自己的优势特长?

据不完全统计,80%的高三学生,不清楚自己要报什么专业,以及将来从事哪种职业?有的人则是完全听从父母的安排,有人听老师的建议,有人追热门,有人查什么专业可以拿高薪.... 而现实就是&#xff1a…