共计 3385 个字符,预计需要花费 9 分钟才能阅读完成。
最近公司 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: 200
sync_main: <_MainThread(MainThread, started 4471512512)>: 193: 200
sync_main: <_MainThread(MainThread, started 4471512512)>: 194: 200
sync_main: <_MainThread(MainThread, started 4471512512)>: 195: 200
sync_main: <_MainThread(MainThread, started 4471512512)>: 196: 200
sync_main: <_MainThread(MainThread, started 4471512512)>: 197: 200
sync_main: <_MainThread(MainThread, started 4471512512)>: 198: 200
sync_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: 200
async_main: <_MainThread(MainThread, started 4471512512)>: 99: 200
async_main: <_MainThread(MainThread, started 4471512512)>: 67: 200
async_main: <_MainThread(MainThread, started 4471512512)>: 93: 200
async_main: <_MainThread(MainThread, started 4471512512)>: 125: 200
async_main: <_MainThread(MainThread, started 4471512512)>: 193: 200
async_main: <_MainThread(MainThread, started 4471512512)>: 100: 200
4.518340110778809
能够看到程序尽管是乱的(56,99,67…)(这是因为程序在协程间不停切换) 然而主线程并没有切换(协程实质还是单线程)。
程序共耗时 4.5 秒
比起同步申请耗时的 16.6 秒 缩短了靠近 73 %!
俗话说得好,一步快,步步快。在耗时方面,” 异步 ” http 的确比同步 http 快了很多。当然,” 协程 ” 不仅仅能在申请效率方面赋能接口测试,把握 “ 协程 ” 后,置信小伙伴们的技术水平也能晋升一个台阶,从而设计出更优良的测试框架。
以上就是本次分享的所有内容,如果你感觉文章还不错,欢送关注公众号:Python 编程学习圈 ,每日干货分享,发送“J”还可支付大量学习材料,内容笼罩 Python 电子书、教程、数据库编程、Django,爬虫,云计算等等。或是返回编程学习网,理解更多编程技术常识。