Python基于基于协程的异步HTTP请求实现:使用asynci

2020-05-24  本文已影响0人  睡不醒的大橘

代码实现

先创建一个基于Flask的server

from flask import Flask
from time import sleep

app = Flask(__name__)

@app.route('/<name>')
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的一些关键字的说明:

详细语法可参考官网:https://docs.python.org/3/library/asyncio-task.html#coroutines


aiohttp

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

详细的语法可以参考官网:https://docs.aiohttp.org/en/stable/index.html

上一篇下一篇

猜你喜欢

热点阅读