python -- 异步、asyncio

news2025/1/8 6:27:38

文章目录

  • 协程
    • 实现协成的方法
      • 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)

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

超市陈列艺术:不仅仅是货品摆放,更是营销策略的体现

品类管理在门店落地的最直观表现就是单品的空间陈列管理,通过陈列细节的差异体现出门店的商品定位与策略。此文分析入木三分,值得学习。 在商品陈列的空间管理领域,不仅要考虑整体的空间陈列,也要对每个商品的空间陈列位置&#…

工作神器大合集

在当代的工作环境里,软件工具扮演了不可或缺的角色,它们的设计初衷就是为了提高工作的效率与质量。下面将推荐五款值得使用的工作效率软件: 1、亿可达 作为一款自动化工具,亿可达被誉为国内版的免费Zaiper。它允许用户无需编程知…

DIYGW可视化开发工具:微信小程序与多端应用开发的利器

一、引言 随着移动互联网的飞速发展,微信小程序以其轻便、易用和跨平台的特点受到了广泛关注。然而,微信小程序的开发相较于传统的H5网页开发,在UI搭建和交互设计上存在一定的挑战。为了应对这些挑战,开发者们一直在寻找更加高效…

Ubuntu20.04.6操作系统安装教程

一、VMware Workstation16安装 选择安装VMware Workstation,登录其官网下载安装包,链接如下: 下载 VMware Workstation Pro 下载后运行安装向导,一直Next即可。 二、Ubuntu镜像下载 ubuntu20.04 选择需要下载的镜像类型下载即…

CobaltStrike权限传递MSF

一、测试环境 操作系统: 1.VMware17 2.kali 6.1.0-kali5-amd64 3.Win10x64 软件: 1.cs4.0 2.metasploit v6.3.4-dev 二、测试思路 1.cs是一款渗透测试工具,但没有漏洞利用的模块,我们可以在拿到目标主机的权限后,将…

代码解读 | Hybrid Transformers for Music Source Separation[05]

一、背景 0、Hybrid Transformer 论文解读 1、代码复现|Demucs Music Source Separation_demucs架构原理-CSDN博客 2、Hybrid Transformer 各个模块对应的代码具体在工程的哪个地方 3、Hybrid Transformer 各个模块的底层到底是个啥(初步感受)&#xff1…

工厂环境中ESD防静电系统对静电灾害的预防与控制

静电在工厂环境中可能造成严重的危害,包括火灾、爆炸和设备损坏等。因此,对于工厂环境中的静电灾害,采取预防和控制措施是非常必要的。ESD防静电系统是一种用来预防和控制静电灾害的重要解决方案,它可以有效地降低静电危害发生的可…

MCGS仿真教学1:单个变量与博途进行通讯

目录 一、博途配置1.1、博途通讯常用配置1.2、博途测试程序 二、MCGS配置2.1、工程配置2.2、设备组态2.3、添加单个变量2.4、添加画面2.4.1、按钮2.4.2、指示灯 三、下载测试 一、博途配置 1.1、博途通讯常用配置 1.2、博途测试程序 二、MCGS配置 2.1、工程配置 选择自己所购…

ubuntu18.04离线源制作

给客户部署有时需要纯内网环境,那这样就连不了网络。 一些包就下载不下来,而大家都知道用deb离线安装是非常麻烦的,各种依赖让你装不出来。 这里教大家打包源。 我准备2台机器,42和41 42可以联网,41不能联网。我想在…

python的a[:2]、a[:] 和a [::] 的区别

一、a[:2] 数据准备 import numpy as np X np.array([[0,1],[2,3],[4,5],[6,7],[8,9],[10,11],[12,13],[14,15],[16,17],[18,19]]) print(X)形成矩阵 print (“X[: 2]:”, X[: 2]) ### :表示索引 0至1行; 二、a[:]和a [::] 在 Python 中,[:] 和 [::…

修改版的VectorDBBench更好用

原版本VectorDBBench的几个问题 在这里就不介绍VectorDBBench是干什么的了,上官网即可。 1.并发数设置的太少 2.测试时长30秒太长 3.连接milvus无用户和密码框,这个是最大的问题 4.修改了一下其它参数 由于很多网友发私信问一些milvus的相关技术问…

钓鱼小助手 —— 借助文心智能体平台打造钓鱼佬神器

前言 🚀前方高能 🚀钓鱼小助手上线了 有没有喜欢钓鱼的程序猿呀,福利来了,特意整了一个钓鱼的小助手,以后钓鱼小技巧都可以咨询了。 走过路过,不要错过,快快体验吧~ 🚀&#x1…

【Three.js】知识梳理二十三:Three.js与其他WebGL库与框架对比

在WebGL开发中,Three.js是一个非常流行的库,它简化了3D图形的创建和渲染过程。然而,市场上还有许多其他的WebGL库,如 Babylon.js、PlayCanvas、PIXI.js 和 Cesium,它们也有各自的特点和优势。本文将对Three.js 与这些常…

翻译《The Old New Thing》- The case of the exception that a catch (…) didn’t catch

The case of the exception that a catch (...) didnt catch - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20240405-00/?p109621 Raymond Chen 2024年04月05日 一位客户认为他们修复了一个bug,但他们仍然因为这个bug而崩溃。…

LogicFlow 学习笔记——4. LogicFlow 基础 边 Edge

边 Edge 和节点一样&#xff0c;LogicFlow 也内置一些基础的边。LogicFlow 的内置边包括&#xff1a; 直线 - line直角折现 - polyline贝塞尔曲线 - bezier 新建 src/views/Example/LogicFlow/Example08.vue 并编写如下代码&#xff1a; <script setup lang"ts&quo…

c#中上传超过30mb的文件,接口一直报404,小于30mb的却可以上传成功

在一次前端实现上传视频文件时,超过30mb的文件上传,访问接口一直报404,但是在Swagger中直接访问接口确是正常的,且在后端控制器中添加了限制特性,如下 但是却仍然报404,在apifox中请求接口也是报404, 网上说: 在ASP.NET Core中,配置请求过来的文件上传的大小限制通常…

FPGA - 全局时钟资源

全局时钟资源是指FPGA内部为实现系统时钟到达FPGA内部各 CLB、IOB&#xff0c;以及BSRAM&#xff08;Block Select RAM&#xff0c;选择性BRAM&#xff09;等基本逻辑单元的延时和抖动最小化&#xff0c;采用全铜层工艺设计和实现的专用缓冲与驱动结构。 由于全局时钟资源的布线…

电子制造业数字化整体解决方案

电子制造行业有特殊的着重点&#xff1a; 高精度要求&#xff1a;电子制造需要极高的精度和质量控制&#xff0c;因为电子组件和电路板的尺寸通常非常小&#xff0c;且对错误和缺陷非常敏感。 快速技术迭代&#xff1a;电子行业的技术迅速发展&#xff0c;产品生命周期短&…

RabbitMQ概述

RabbitMQ RabbitMQ概述 RabbitMQ是一个开源的消息代理&#xff08;message broker&#xff09;系统&#xff0c;最初由Rabbit Technologies Ltd开发&#xff0c;并在开源社区的支持下不断发展和完善。它提供了强大的消息传递机制&#xff0c;被广泛应用于构建分布式系统和应用…

vue3 proxy对象转为原始对象

https://cn.vuejs.org/api/reactivity-advanced.html#toraw import { toRaw } from "vue";const foo {} const reactiveFoo reactive(foo)console.log(toRaw(reactiveFoo) foo) // true 人工智能学习网站 https://chat.xutongbao.top