前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python协程初体验

python协程初体验

作者头像
测试加
发布2022-06-21 16:16:48
3500
发布2022-06-21 16:16:48
举报

前言

在了解了Python并发编程的多线程和多进程之后,我们来了解一下基于asyncio的异步IO编程 => 协程

协程

协程(Coroutine)又称微线程、纤程,协程不是进程或线程,其执行过程类似于 Python 函数调用,Python 的 asyncio 模块实现的异步IO编程框架中,协程是对使用 async 关键字定义的异步函数的调用

一个进程包含多个线程,类似于一个人体组织有多种细胞在工作,同样,一个程序可以包含多个协程。多个线程相对独立,线程的切换受系统控制。同样,多个协程也相对独立,但是其切换由程序自己控制

那协程有什么优势呢?

  • 执行效率极高,因为子程序切换(函数)不是线程切换,由程序自身控制,没有切换线程的开销。所以与多线程相比,线程的数量越多,协程性能的优势越明显
  • 不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在控制共享资源时也不需要加锁,因此执行效率高很多

Python3.x协程

Python3.x还提供了如下方式实现协程:asyncio + yield from (python3.4+) asyncio + async/await (python3.5+)

Python3.4以后引入了asyncio模块,可以很好的支持协程

asyncio

evnt_loop: 事件循环,相当于一个无限循环,我们可以把一些函数注册到这个事件循环上,当满足条件发生的时候,就会调用对应的处理方法

coroutine: 中文翻译叫协程,在 Python 中常指代为协程对象类型,我们可以将协程对象注册到时间循环中,它会被事件循环调用。我们可以使用 async 关键字来定义一个方法,这个方法在调用时不会立即被执行,而是返回一个协程对象

task: 任务,它是对协程对象的进一步封装,包含了任务的各个状态

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

async

定义异步函数

代码语言:javascript
复制
async def async_function():
    print('Number:', 1)
    return 1

print(async_function())    

输出:
返回一个协程对象
<coroutine object async_function at 0x10a4b0f10>

调用send方法激活

代码语言:javascript
复制
print(async_function().send(None))

异步函数

代码语言:javascript
复制
async def async_function():
    print('Number:', 1)
    r = requests.get('http://www.baidu.com')
    return r


coroutine = async_function()
loop = asyncio.get_event_loop()
t = loop.run_until_complete(coroutine)
print(t)
print('After calling loop')

异步函数task

代码语言:javascript
复制
coroutine = async_function()
loop = asyncio.get_event_loop()
task = loop.create_task(coroutine)
print('Task:', task)
loop.run_until_complete(task)
print('Task:', task)
print('After calling loop')

输出:  coroutine 对象多了运行状态,比如 running、finished 等

Task: <Task pending coro=<async_function() running at async_t.py:104>>
Number: 1
Task: <Task finished coro=<async_function() done, defined at async_t.py:104> result=<Response [200]>>
After calling loop

异步函数ensure_future

代码语言:javascript
复制
task = asyncio.ensure_future(coroutine)
print('Task:', task)
loop = asyncio.get_event_loop()
loop.run_until_complete(task)
print('Task:', task)
print('After calling loop')

异步函数绑定回调

代码语言:javascript
复制
async def async_function():
    print('Number:', 1)
    r = requests.get('http://www.baidu.com')
    return r

def callback(task):
    print('Status:', task.result())

task = asyncio.ensure_future(coroutine)
task.add_done_callback(callback)
print('Task:', task)

loop = asyncio.get_event_loop()
loop.run_until_complete(task)
print('Task:', task)    

异步函数网络并发执行

代码语言:javascript
复制
import requests_async as requests
async def post_requests():
    print("Hello world!")
    async with requests.Session() as session:
        print("create Session statr")
        response = await session.get('https://example.org')
        print("create Session over")
        print(response.status_code)
        # print(response.text)

tasks = [post_requests() for host in ['www.sina.com.cn', 'www.sohu.com', 'www.163.com']]

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
print('Task:', tasks)        

异步函数网络请求

代码语言:javascript
复制
async def get(url):
    return requests.get(url)


async def request():
    url = 'http://127.0.0.1:5000/api'
    print('Waiting for', url)
    response = await get(url)
    print('Get response from', url, 'Result:', response.text)


tasks = [asyncio.ensure_future(request()) for _ in range(5)]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

多任务异步

代码语言:javascript
复制
import asyncio
import requests


async def request():
    url = 'https://www.baidu.com'
    status = requests.get(url)
    return status


tasks = [asyncio.ensure_future(request()) for _ in range(5)]
print('Tasks:', tasks)

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

for task in tasks:
    print('Task Result:', task.result())

aiohttp异步请求

代码语言:javascript
复制
async def aiohttp_get():
    url = 'http://127.0.0.1:5000/api'
    print('Waiting for', url)
    session = aiohttp.ClientSession()
    response = await session.get(url)
    result = await response.text()
    print('Get response from', url)
    session.close()
    return result


tasks = [asyncio.ensure_future(aiohttp_get()) for _ in range(5)]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

结尾

上面就是python协程的一些简单体验,后续会结合一些协程实战项目,分享更多使的技巧~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-05-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 测试加 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 协程
    • 那协程有什么优势呢?
      • Python3.x协程
        • asyncio
          • async
          • 结尾
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档