python asyncio与aiohttp_Python基于基于协程的异步HTTP请求实现:使用asyncio 与 aiohttp...

代码实现

先创建一个基于Flask的server

from flask import Flask

from time import sleep

app = Flask(__name__)

@app.route('/')

def hello_world(name):

sleep(5)

return f'Hello {name}!'

if __name__ == '__main__':

app.run()

client使用asyncio 与 aiohttp进行异步HTTP请求

async def fetch(session, url):

async with session.get(url) as response:

return await response.text()

async def main(name_list):

async with aiohttp.ClientSession() as session:

tasks = [asyncio.ensure_future(fetch(session, f'http://127.0.0.1:5000/{name}')) for name in name_list]

res = await asyncio.gather(*tasks)

print(res)

if __name__ == '__main__':

loop = asyncio.get_event_loop()

name_list = ['a', 'b', 'c']

start = time.time()

loop.run_until_complete(main(name_list))

end = time.time()

print('elapsed time = ' + str(end - start))

loop.close()

先运行server, 然后运行client,client的输出:

['Hello a!', 'Hello b!', 'Hello c!']

elapsed time = 5.019996881484985

可见三个http get请求是异步进行的。

要解释以上的代码,首先介绍一下Python协程

Python协程 (Coroutine)

一个例子

借用一篇博客中的例子:

“假设有1个洗衣房,里面有10台洗衣机,有一个洗衣工在负责这10台洗衣机。那么洗衣房就相当于1个进程,洗衣工就相当1个线程。如果有10个洗衣工,就相当于10个线程,1个进程是可以开多线程的。这就是多线程!

那么协程呢?先不急。大家都知道,洗衣机洗衣服是需要等待时间的,如果10个洗衣工,1人负责1台洗衣机,这样效率肯定会提高,但是不觉得浪费资源吗?明明1 个人能做的事,却要10个人来做。只是把衣服放进去,打开开关,就没事做了,等衣服洗好再拿出来就可以了。就算很多人来洗衣服,1个人也足以应付了,开好第一台洗衣机,在等待的时候去开第二台洗衣机,再开第三台,……直到有衣服洗好了,就回来把衣服取出来,接着再取另一台的(哪台洗好先就取哪台,所以协程是无序的)。这就是计算机的协程!洗衣机就是执行的方法。”

协程的特点

协程,又称微线程。协程的作用是在执行函数A时可以随时中断去执行函数B,然后中断函数B继续执行函数A(可以自由切换)。但这一过程并不是函数调用,这一整个过程看似像多线程,然而协程只有一个线程执行。

协程很适合处理IO密集型程序的效率问题。协程的本质是个单线程,它不能同时将 单个CPU 的多个核用上,因此对于CPU密集型程序协程需要和多进程配合。

asyncio关键字

asyncio是python3.4之后引入的协程模块。关于asyncio的一些关键字的说明:

event_loop 事件循环:程序开启一个无限循环,把一些函数注册到事件循环上,当满足事件发生的时候,调用相应的协程函数

coroutine 协程:协程对象,指一个使用async关键字定义的函数,它的调用不会立即执行函数,而是会返回一个协程对象。协程对象需要注册到事件循环,由事件循环调用。

task 任务:一个协程对象就是一个原生可以挂起的函数,任务则是对协程进一步封装,其中包含了任务的各种状态

future: 代表将来执行或没有执行的任务的结果。它和task上没有本质上的区别

async/await 关键字:python3.5用于定义协程的关键字,async定义一个协程,声明函数挂起的这个切换点,一般是一个耗时的IO操作。

run_until_complete方法:将协程包装成为了一个任务(task)对象. task对象是Future类的子类,保存了协程运行后的状态,用于未来获取协程的结果。run_until_complete会运行直到Future结束,返回Future的结果或者抛出exception。

asyncio.ensure_future(coroutine):用于创建task

asyncio.gather(*tasks):返回coroutine或者futures生成的结果。结果是一个list,顺序和输入的顺序一致,与返回结果的顺序无关。

aiohttp

aiohttp是一个基于asyncio的异步HTTP client和server, 在python3.5之后加入

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值