Python运维之协程

目录

一、定义协程

二、并发

三、异步请求


协程是一种轻量级的线程,它通过保存和恢复寄存器上下文和栈来实现调度切换,从而保留函数执行的状态

这种机制使得协程在处理I/O密集型任务时效率较高,因为它们可以在I/O操作期间让出CPU,以执行其他任务。与多线程相比,协程在同一线程内进行调用,减少了上下文切换的开销。

简而言之,协程通过在函数执行过程中灵活地让出和收回控制权提高了程序的并发性能

一、定义协程

python3.4加入协程的概念,以生成器对象为基础。Python3.5增加了async/await,下面以asyncio为基础介绍协程的使用。

 import asyncioimport time​async def task():print(f"{time.strftime('%H:%M:%S')} task 开始")time.sleep(2)print(f"{time.strftime('%H:%M:%S')} task 结束")​coroutine = task()print(f"{time.strftime('%H:%M:%S')} 产生协程对象 {coroutine},函数并未被调用")loop = asyncio.get_event_loop()print(f"{time.strftime('%H:%M:%S')} 开始调用协程任务")start = time.time()loop.run_until_complete(coroutine)end = time.time()print(f"{time.strftime('%H:%M:%S')} 结束调用协程任务,耗时{end - start} 秒")

提示:首先引入asyncio,主要才可以使用async和await关键字(async定义一个协程await用于临时挂起一个函数或方法的执行),接着使用async定义一个协程方法,然后直接调用该方法,但该方法没有被执行,而是返回一个coroutine协程对象。 使用get_event_loop()方法创建一个事件循环loop,并调用loop对象的run_until_complete()方法协程注册到事件循环loop中,然后启动,这才完成执行。

我们还可以为任务绑定回调函数

 import asyncioimport time​async def task():print(f"{time.strftime('%H:%M:%S')} task 开始")time.sleep(2)print(f"{time.strftime('%H:%M:%S')} task 结束")return "运行结束"​def callback(task):print(f"{time.strftime('%H:%M:%S')} 回调函数开始执行")print(f"状态:{task.result()}")​coroutine = task()print(f"{time.strftime('%H:%M:%S')} 产生协程对象 {coroutine},函数并未被调用")task = asyncio.ensure_future(coroutine)task.add_done_callback(callback)loop = asyncio.get_event_loop()print(f"{time.strftime('%H:%M:%S')} 开始调用协程任务")start = time.time()loop.run_until_complete(task)end = time.time()print(f"{time.strftime('%H:%M:%S')} 结束调用协程任务,耗时{end - start} 秒")

定义了一个协程方法和一个普通方法作为回调函数,回调函数接收一个参数是task对象,asyncio.ensure_future(coroutine)可以返回task对象add_done_callback()为task对象增加一个回调任务。这样我们就定义好了一个coroutine对象和一个回调方法,执行的结果是当couroutine对象执行完毕之后,就去执行声明的callback方法。

二、并发

上述之定义了一个协程任务,如果要多次并尽可能提高效率,可以定义一个task列表,然后使用asyncio的wait()方法执行即可:

 import asyncioimport time​async def task():print(f"{time.strftime('%H:%M:%S')} task 开始")# 异步调用asynico.sleep(1):await asyncio.sleep(2)# time.sleep(2)time.sleep(2)print(f"{time.strftime('%H:%M:%S')} task 结束")return "运行结束"​# 获取EventLoop:loop = asyncio.get_event_loop()# 执行coroutinetasks = [task() for _ in range(5)]start = time.time()loop.run_until_complete(asyncio.wait(tasks))loop.close()end = time.time()print(f"用时{end - start}")

关键字await后面的对象必须是以下类型之一:

  • 一个原生coroutine对象
  • 一个由types.coroutine()修饰的生成器,这个生成器可以返回coroutine对象
  • 一个包含await方法的对象返回的一个迭代器

asyncio.sleep(2)是一个由coroutine修饰的生成器对象,表示等待2秒。

三、异步请求

以常用的网络请求为例,网络请求较多的就是I/O密集型任务。

启动一个简单的Web服务器

 from flask import Flaskimport time​app =  Flask(__name__)​@app.route('/')def index():time.sleep(3)return 'Hello world!'​if __name__ == '__main__':app.run(threaded=True)      # 表明多线程模式启动

如果不开启多线程模式,那么同一时刻遇到多个请求时,只能顺次处理,这样即使我们使用协程异步请求这个服务,也只能一个一个排队。

 import asyncioimport requestsimport time​start = time.time()​async def request():url = 'http://127.0.0.1:5000'print(f'{time.strftime("%H:%M:%S")} 请求 {url}')response = requests.get(url)print(f'{time.strftime("%H:%M:%S")} 得到响应 {response.text}')​tasks = [asyncio.ensure_future(request()) for _ in range(5)]loop = asyncio.get_event_loop()loop.run_until_complete(asyncio.wait(tasks))​end = time.time()print(f"耗时{end-start}")

耗时15秒,其实要实现异步处理,必须先有挂起的操作,当一个任务需要等待I/O结果时,可以挂起当前任务,让出CPU的控制权,转去执行其他任务,这样才能充分利用好资源。上述代码串行走,没有实现挂起

要实现异步,使用await将耗时等待的操作挂起让出控制权。当协程执行时遇到await时间循环就会将本协程挂起,转去执行别的协程,直到其他的协程挂起或执行完毕,修改代码:

 import asyncioimport requestsimport time​async def get(url):return requests.get(url)​async def request():url = 'http://127.0.0.1:5000'print(f'{time.strftime("%H:%M:%S")} 请求 {url}')response = await get(url)print(f'{time.strftime("%H:%M:%S")} 得到响应 {response.text}')​start = time.time()tasks = [asyncio.ensure_future(request()) for _ in range(5)]loop = asyncio.get_event_loop()loop.run_until_complete(asyncio.wait(tasks))end = time.time()print(f"耗时{end-start}")

上述代码将请求页面的方法封装为一个coroutine读写,在request方法中尝试使用await挂起当前执行的I/O,发现还是15s,原来request不是异步请求,aiohttp是一个支持异步请求的库,将其配合使用即可实现异步请求操作:

 import asyncioimport aiohttpimport time​now = lambda :time.strftime("%H:%M:%S")​async def get(url):async with aiohttp.ClientSession() as session:  # 使用异步上下文管理器response = await session.get(url)result = await response.text()return resultasync def request():url = 'http://127.0.0.1:5000'print(f'{now()} 请求 {url}')result = await get(url)print(f'{now()} 得到响应 {result}')​start = time.time()tasks = [asyncio.ensure_future(request()) for _ in range(5)]loop = asyncio.get_event_loop()loop.run_until_complete(asyncio.wait(tasks))end = time.time()print(f"耗时{end-start}")

运行时间只有3秒,扩大20倍还是3秒。可见,异步协程在爬虫项目值速度提升是非常可观了。

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

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

相关文章

5g视频彩信和普通彩信有什么区别

5G视频彩信和普通彩信有什么区别 随着科技的不断进步,手机通信技术也在迅速发展。5G技术的出现,为彩信传输提供了更高的速度和更广的带宽。在这种背景下,5G视频彩信和普通彩信成为了人们关注的焦点。本文将探讨这两种彩信的区别。 5G视频彩信…

Java数组的应用---选择排序(Select Sort)

一、需求:选择排序(Select Sort),进行升序显示 在一组排列中把最大的数取出来放在一个新的列表里,再删去,在取最大的数出来,依次类推直到取到最后一个数字 二、定义一个无序的一维数组,并输出数组 程序运…

BBS客户端服务器的编写

根据网络编程中的内容,我们本篇文章将讲解一个bbs通信的项目,首先让我们了解一下什么是bbs. 一、bbs介绍 BBS,即Bulletin Board System的缩写,中文译为“电子公告板系统”或“网络论坛”。它是一个在网络上进行信息交流和讨论的…

重装前端整体流程

用户管理 --汇总 -- 明细-CSDN博客 一、node 这个看环境变量 2023最新版Node.js下载安装及环境配置教程(非常详细)从零基础入门到精通,看完这一篇就够了_nodejs安装及环境配置-CSDN博客 配置到国内镜像的时候,去看,淘…

代码随想录算法训练营第六十二天|503.下一个更大元素II、42.接雨水

代码随想录算法训练营第六十二天|503.下一个更大元素II、42.接雨水 503.下一个更大元素II 给定一个循环数组 nums ( nums[nums.length - 1] 的下一个元素是 nums[0] ),返回 nums 中每个元素的 下一个更大元素 。 数字 x 的 下一个更大的元…

小程序(三)

十三、自定义组件 (二)数据方法声明位置 在js文件中 A、数据声明位置:data中 B、方法声明位置methods中,这点和普通页面不同! Component({/*** 组件的属性列表*/properties: {},/*** 组件的初始数据*/data: {isCh…

【系统架构师】-案例篇(七)信息安全

某软件公司拟开发一套信息安全支撑平台,为客户的局域网业务环境提供信息安全保护。该支撑平台的主要需求如下: 1.为局域网业务环境提供用户身份鉴别与资源访问授权功能; 2.为局域网环境中交换的网络数据提供加密保护; 3.为服务…

26、Qt使用QFontDatabase类加载ttf文件更改图标颜色

一、图标下载 iconfont-阿里巴巴矢量图标库 点击上面的链接,在打开的网页中搜索自己要使用的图标,如:最大化 找到一个自己想用图标,选择“添加入库” 点击“购物车”图标 能看到刚才添加的图标,点击“下载代码”(需要…

js教程(13)

一、作用域 作用域规定了变量能够被访问的范围,而离开变量作用域的变量则不能被访问(有时也叫变量的生命周期)。作用域又分为局部作用域和全局作用域。 1.局部作用域 在函数或代码块内部声明的变量只能在其内部被访问,在外部无法…

牛客周赛 Round 41 C-F

C 小红的循环移位 思路&#xff1a; 一个数是不是四的倍数&#xff0c;只用看最后两位是否能够整除4即可。 #include <bits/stdc.h>using namespace std; const int N 1e6 5; typedef long long ll; typedef pair<ll, ll> pll; typedef array<ll, 3> p3;…

暗区突围进不去/游戏无法启动/掉帧卡顿/报错的解决方法

暗区突围是一款高拟真硬核射击手游&#xff0c;打造了全新的沉浸式暗区战局体验&#xff0c;发行商是腾讯公司。这个游戏名词虽然看起来有些陌生&#xff0c;但其本身的玩法内核毫无疑问的是&#xff0c;这款游戏在画面质量和枪械操作方面&#xff0c;都是手游市场上同类游戏中…

【vulhub靶场】Apache 中间件漏洞复现

【vulhub靶场】Apache 中间件漏洞复现 一、Apache HTTPD 换行解析漏洞&#xff08;CVE-2017-15715&#xff09;1. 漏洞详情2. 影响版本3. 漏洞复现 二、Apache多后缀解析漏洞&#xff08;apache_parsing_vulnerability&#xff09;1. 漏洞详情2. 漏洞复现 三、Apache HTTP Serv…

【LLM 论文】Step-Back Prompting:先解决更高层次的问题来提高 LLM 推理能力

论文&#xff1a;Take a Step Back: Evoking Reasoning via Abstraction in Large Language Models ⭐⭐⭐⭐ Google DeepMind, ICLR 2024, arXiv:2310.06117 论文速读 该论文受到的启发是&#xff1a;人类再解决一个包含很多细节的具体问题时&#xff0c;先站在更高的层次上解…

第8章.STM32开发方式(库函数)介绍

目录 0. 《STM32单片机自学教程》专栏 8.1 单片机的开发方式 8.1.1 直接操作寄存器 8.1.2 使用库函数 8.2 STM32的库函数 8.2.1 标准外设库(STD库) 8.2.2 HAL库 8.2.3 LL库 0. 《STM32单片机自学教程》专栏 本文作为专栏《STM32单片机自学教程》专栏其中的一…

数据库调优-SQL语句优化

2. SQL语句优化 sql 复制代码 # 请问这两条SQL语句有什么区别呢&#xff1f;你来猜一猜那条SQL语句执行查询效果更好&#xff01; select id from sys_goods where goods_name华为 HUAWEI 麦芒7 魅海蓝 6G64G 全网通; ​ select id from sys_goods where goods_id14967325985…

搜索的未来:OpenAI 的 GPT 如何彻底改变行业

搜索的未来&#xff1a;OpenAI 的 GPT 如何彻底改变行业 概述 搜索引擎格局正处于一场革命的风口浪尖&#xff0c;而 OpenAI 的 GPT 处于这场变革的最前沿。最近出现了一种被称为“im-good-gpt-2-chatbot”的神秘聊天机器人&#xff0c;以及基于 ChatGPT 的搜索引擎的传言&am…

MySQL索引(聚簇索引、非聚簇索引)

了解MySQL索引详细&#xff0c;本文只做整理归纳&#xff1a;https://blog.csdn.net/wangfeijiu/article/details/113409719 概念 索引是对数据库表中一列或多列的值进行排序的一种结构&#xff0c;使用索引可快速访问数据库表中的特定信息。 索引分类 主键索引&#xff1a…

C++对象的赋值

同类的对象之间可以互相赋值&#xff0c;即一个对象的值可以赋值给另一个对象。对象之间的赋值通过“”进行。默认就是把一个对象所有非static数据成员的值依次赋值给另一个对象。 对象赋值的一般形式为&#xff1a; 对象名1 对象名2; 注意:对象名1和对象名2必须是属于同一个…

黑客如何进行IP伪装

在进行互联网访问时候&#xff0c;我们如果被查到IP访问记录&#xff0c;就能根据IP查到具体位置&#xff0c;如果从事非法事情就会被请去喝茶。那么IP是什么&#xff1f;为什么可以根据IP进行查找并且分析主机数据&#xff1f; IP是Internet Protocol&#xff08;网际互连协议…

《TAM》论文笔记(上)

原文链接 [2005.06803] TAM: Temporal Adaptive Module for Video Recognition (arxiv.org) 原文代码 GitHub - liu-zhy/temporal-adaptive-module: TAM: Temporal Adaptive Module for Video Recognition 原文笔记 What&#xff1a; TAM: Temporal Adaptive Module for …