0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Python后端项目的协程是什么

Linux爱好者 来源:Python编程时光 作者:Python编程时光 2021-09-23 14:38 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

最近公司 Python 后端项目进行重构,整个后端逻辑基本都变更为采用“异步”协程的方式实现。看着满屏幕经过 async await(协程在 Python 中的实现)修饰的代码,我顿时感到一脸懵逼,不知所措。

虽然之前有了解过“协程”是什么东西,但并没有深入探索,于是正好借着这次机会可以好好学习一下。

什么是协程?

简单来说,协程是一种基于线程之上,但又比线程更加轻量级的存在。对于系统内核来说,协程具有不可见的特性,所以这种由 程序员自己写程序来管理的轻量级线程又常被称作 “用户空间线程”。

协程比多线程好在哪呢?

线程的控制权在操作系统手中,而 协程的控制权完全掌握在用户自己手中,因此利用协程可以减少程序运行时的上下文切换,有效提高程序运行效率。

建立线程时,系统默认分配给线程的 栈 大小是 1 M,而协程更轻量,接近 1 K 。因此可以在相同的内存中开启更多的协程。

由于协程的本质不是多线程而是单线程,所以不需要多线程的锁机制。因为只有一个线程,也不存在同时写变量而引起的冲突。在协程中控制共享资源不需要加锁,只需要判断状态即可。所以协程的执行效率比多线程高很多,同时也有效避免了多线程中的竞争关系。

协程的适用 & 不适用场景

适用场景:协程适用于被阻塞的,且需要大量并发的场景。

不适用场景:协程不适用于存在大量计算的场景(因为协程的本质是单线程来回切换),如果遇到这种情况,还是应该使用其他手段去解决。

初探异步 http 框架 httpx

至此我们对 “协程” 应该有了个大概的了解,但故事说到这里,相信有朋友还是满脸疑问:“协程” 对于接口测试有什么帮助呢?不要着急,答案就在下面。

相信用过 Python 做接口测试的朋友都对 requests 库不陌生。requests 中实现的 http 请求是同步请求,但其实基于 http 请求 IO 阻塞的特性,非常适合用协程来实现 “异步” http 请求从而提升测试效率。

相信早就有人注意到了这点,于是在 Github 经过了一番探索后,果不其然,最终寻找到了支持协程 “异步” 调用 http 的开源库: httpx

什么是 httpx

httpx 是一个几乎继承了所有 requests 的特性并且支持 “异步” http 请求的开源库。简单来说,可以认为 httpx 是强化版 requests。

下面大家可以跟着我一起见识一下 httpx 的强大

安装

httpx 的安装非常简单,在 Python 3.6 以上的环境执行

pip install httpx

最佳实践

俗话说得好,效率决定成败。我分别使用了 httpx 异步 和 同步 的方式对批量 http 请求进行了耗时比较,来一起看看结果吧~

首先来看看同步 http 请求的耗时表现:

import asyncio

import httpx

import threading

import time

def sync_main(url, sign):

response = httpx.get(url).status_code

print(f‘sync_main: {threading.current_thread()}: {sign}2 + 1{response}’)

sync_start = time.time()

[sync_main(url=‘http://www.baidu.com’, sign=i) for i in range(200)]

sync_end = time.time()

print(sync_end - sync_start)

代码比较简单,可以看到在 sync_main 中则实现了同步 http 访问百度 200 次。

运行后输出如下(截取了部分关键输出…):

sync_main: 《_MainThread(MainThread, started 4471512512)》: 192: 200sync_main: 《_MainThread(MainThread, started 4471512512)》: 193: 200sync_main: 《_MainThread(MainThread, started 4471512512)》: 194: 200sync_main: 《_MainThread(MainThread, started 4471512512)》: 195: 200sync_main: 《_MainThread(MainThread, started 4471512512)》: 196: 200sync_main: 《_MainThread(MainThread, started 4471512512)》: 197: 200sync_main: 《_MainThread(MainThread, started 4471512512)》: 198: 200sync_main: 《_MainThread(MainThread, started 4471512512)》: 199: 200

16.56578803062439

可以看到在上面的输出中, 主线程没有进行切换(因为本来就是单线程啊喂!)请求按照顺序执行(因为是同步请求)。

程序运行共耗时 16.6 秒

下面我们试试 “异步” http 请求:

import asyncio

import httpx

import threading

import time

client = httpx.AsyncClient()

async def async_main(url, sign):

response = await client.get(url)

status_code = response.status_code

print(f‘async_main: {threading.current_thread()}: {sign}:{status_code}’)

loop = asyncio.get_event_loop()

tasks = [async_main(url=‘http://www.baidu.com’, sign=i) for i in range(200)]

async_start = time.time()

loop.run_until_complete(asyncio.wait(tasks))

async_end = time.time()

loop.close()

print(async_end - async_start)

上述代码在 async_main 中用 async await 关键字实现了“异步” http,通过 asyncio ( 异步 io 库请求百度首页 200 次并打印出了耗时。

运行代码后可以看到如下输出(截取了部分关键输出…)

async_main: 《_MainThread(MainThread, started 4471512512)》: 56: 200async_main: 《_MainThread(MainThread, started 4471512512)》: 99: 200async_main: 《_MainThread(MainThread, started 4471512512)》: 67: 200async_main: 《_MainThread(MainThread, started 4471512512)》: 93: 200async_main: 《_MainThread(MainThread, started 4471512512)》: 125: 200async_main: 《_MainThread(MainThread, started 4471512512)》: 193: 200async_main: 《_MainThread(MainThread, started 4471512512)》: 100: 200

4.518340110778809

可以看到顺序虽然是乱的(56,99,67…) (这是因为程序在协程间不停切换) 但是主线程并没有切换 (协程本质还是单线程 )。

程序共耗时 4.5 秒

比起同步请求耗时的 16.6 秒 缩短了接近 73 %!

俗话说得好,一步快,步步快。 在耗时方面,“异步” http 确实比同步 http 快了很多。当然,“协程” 不仅仅能在请求效率方面赋能接口测试, 掌握 “协程”后,相信小伙伴们的技术水平也能提升一个台阶,从而设计出更优秀的测试框架。

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 操作系统
    +关注

    关注

    37

    文章

    7329

    浏览量

    128647
  • 代码
    +关注

    关注

    30

    文章

    4941

    浏览量

    73151
  • python
    +关注

    关注

    57

    文章

    4858

    浏览量

    89590

原文标题:强化版的 requests,这个库真牛 x

文章出处:【微信号:LinuxHub,微信公众号:Linux爱好者】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    FreeRTOS任务和协的区别是什么

    1.堆栈 是没有堆栈分配的,是所有创建的共同使用一个堆栈空间,这相比于任务来说,减少了RAM的使用空间。 2. 调度和优先级
    发表于 12-08 08:18

    ucos与freertos哪个好?

    选择uCOS或FreeRTOS取决于项目的具体需求和资源限制。 FreeRTOS的优点包括: 更小的内核ROM和RAM占用,特别是在RAM方面,适合资源受限的嵌入式系统。 支持
    发表于 12-05 07:13

    基于E203 NICE处理器扩展指令

    1、实现功能 基于官方提供的demo nice的硬件代码,设计一个基于e203 nice处理的加法器。 2NICE处理器理论学习 nice处理器的作用主要是用于控制通路的管理 去年
    发表于 10-21 14:35

    通入选2025年安防产品和技术典型应用案例

    近日,广州万通信息技术有限公司“基于可信计算的主动标识载体及在智能家居行业应用项目”,凭借其创新的技术架构、显著的实战成效及卓越的可推广价值,经过企业申报、地方协会重点推荐及专家多维度严苛评审,成功入选“2025年安防产品和技术典型应用案例”。
    的头像 发表于 10-11 10:10 455次阅读

    使用RT-Thread studio 开发RT-Thread Nano项目的时候 串口的驱动是要自己写吗?

    刚入坑。使用RT-Thread studio 开发RT-Thread 标准板项目的时候直接使用里边的串口uart_dev=rt_device_find(“uart5”);然后操作设备,在开发RT-Thread Nano项目的时候,串口的驱动是需要自己写吗。
    发表于 09-26 08:14

    如何选择适合自己项目的通信协议评估工具?

    LZ-DZ200电能质量在线监测装置 选择适合项目的通信协议评估工具,核心是 对齐项目需求与工具能力 ,避免 “过度选型”(用高端工具测简单场景)或 “功能不足”(用轻量工具测复杂协议)。以下是分步
    的头像 发表于 08-27 09:19 441次阅读
    如何选择适合自己<b class='flag-5'>项目的</b>通信协议评估工具?

    进迭时空 V8 RISC-V 后端优化

    前言V8是Google开发及开源的JavaScript和WebAssembly语言编译引擎,是Chromium项目的一部分,主要应用于Chrome浏览器和Node.js等项目,在浏览器生态中发
    的头像 发表于 07-31 09:02 793次阅读
    进迭时空 V8 RISC-V <b class='flag-5'>后端</b>优化

    紫光国芯如何助力芯片后端设计

    众所周知,芯片产品的诞生需要经历设计、制造、封测等阶段,其中的芯片设计又包括架构、代码、验证、中端、后端等步骤。后端设计将抽象的代码转化成为可制造、功能正确、满足性能功耗指标的物理图纸数据,最终由芯片生产工厂制造。
    的头像 发表于 07-08 16:40 833次阅读

    LuatOS深度解析:小白也能10分钟学会,代码效率直接起飞!

    嵌入式开发如何兼顾效率与简洁?LuatOS给出完美答案!它用类线程的语法封装异步逻辑,让多任务开发像单线程一样简单。本文用图文并茂的方式拆解原理,10分钟带你轻松入门!   L
    的头像 发表于 04-10 15:23 456次阅读
    LuatOS<b class='flag-5'>协</b><b class='flag-5'>程</b>深度解析:小白也能10分钟学会,代码效率直接起飞!

    10分钟上手写代码,LuatOS轻松掌握!

    10分钟学会LuatOS,从此你的程序也能像通勤族利用碎片时间一样游刃有余。现在就去动手试一试,开启异步编程新体验! 写给第一次听说的你‌: 别怕!
    的头像 发表于 04-10 15:18 495次阅读
    10分钟上手写代码,LuatOS<b class='flag-5'>协</b><b class='flag-5'>程</b>轻松掌握!

    电机冲刺北交所上市

    近日,北交所网站显示,常州三电机股份有限公司(以下简称“三电机”)答复了第二轮问询函。三电机此前于2023年12月29日IPO申请获北交所受理。
    的头像 发表于 03-28 17:53 1762次阅读

    进程、线程、傻傻分不清?一文带你彻底扒光它们的\"底裤\"!

    各位程序员朋友(和假装懂技术的同事):如果你在面试时被问到:\"请用奶茶店类比进程、线程和协\",而你回答:\"进程是老板,线程是员工,是兼职...\"
    发表于 03-26 09:27

    芯片前端和后端制造工艺的区别

    通常,我们将芯片的生产过程划分为前端制程和后端制程两大阶段,其中前端制程专注于芯片的制造,而后端制程则关注于芯片的封装。
    的头像 发表于 02-12 11:27 2442次阅读
    芯片前端和<b class='flag-5'>后端</b>制造工艺的区别

    适用于MySQL和MariaDB的Python连接器:可靠的MySQL数据连接器和数据库

    和 Linux 的 wheel 包分发。 直接连接 该解决方案使您能够通过 TCP/IP 建立与 MySQL 或者 MariaDB 数据库服务器的直接连接,而无需数据库客户端库。另外直接连接可以提高 Python 应用
    的头像 发表于 01-17 12:18 845次阅读
    适用于MySQL和MariaDB的<b class='flag-5'>Python</b>连接器:可靠的MySQL数据连接器和数据库

    【实战】人工智能0基础入门:基于Python+OpenCV的车牌识别项目(课程+平台实践)

    01引言随着智能交通系统的发展,车牌识别技术在车辆管理、交通监控、停车收费等多个领域发挥着重要作用。接下来小编将带你深入了解车牌识别项目的全流程,从理论基础到实际应用,让你掌握如何构建一个高效、准确
    的头像 发表于 12-16 10:43 1181次阅读
    【实战】人工智能0基础入门:基于<b class='flag-5'>Python</b>+OpenCV的车牌识别<b class='flag-5'>项目</b>(课程+平台实践)