Python协程asyncio异步编程笔记分享

目录
  • 1.事件循环
  • 2.协程和异步编程
    • 2.1基本使用
    • 2.2await
    • 2.3Task对象

1.事件循环

可以理解成为一个死循环,去检查任务列表中的任务,如果可执行就去执行,如果检查不到就是不可执行的,那就忽略掉去执行其他可执行的任务,如果IO结束了(比如说去百度下载图片,下载完了就会变成可执行任务)再去执行下载完成之后的逻辑

#这里的任务是有状态的,比如这个任务已经完成或者正在执行或者正在IO等待
任务列表 = [ 任务1, 任务2, 任务3,... ]
while True:
    可执行的任务列表,已完成的任务列表 = 去任务列表中检查所有的任务,将'可执行'和'已完成'的任务返回
    for 就绪任务 in 可执行的任务列表:
        执行已就绪的任务
    for 已完成的任务 in 已完成的任务列表:
        在任务列表中移除 已完成的任务
    如果 任务列表 中的任务都已完成,则终止循环
#在编写程序时候可以通过如下代码来获取和创建事件循环。
import asyncio
loop = asyncio.get_event_loop()
#将任务放到任务列表,让事件循环去检测任务的状态(是否可运行,是否IO)
loop.loop.run_until_complete(任务)

2.协程和异步编程

协程函数,定义形式为 async def 的函数。
协程对象,调用 协程函数() 所返回的对象。

# 定义一个协程函数
async def func():
    pass
# 调用协程函数,返回一个协程对象(内部代码不会执行)
result = func()

2.1 基本使用

程序中,如果想要执行协程函数的内部代码,需要 事件循环 和 协程对象 配合才能实现
示例1:

import asyncio
async def func():
    print("协程内部代码")
# 调用协程函数,返回一个协程对象。
result = func()
# 方式一
# loop = asyncio.get_event_loop() # 创建一个事件循环
# loop.run_until_complete(result) # 将协程当做任务提交到事件循环的任务列表中,协程执行完成之后终止。
# 方式二
# 本质上方式一是一样的,内部先 创建事件循环 然后执行 run_until_complete,一个简便的写法。
# asyncio.run 函数在 Python 3.7 中加入 asyncio 模块,
asyncio.run(result)

2.2 await

await+可等待对象(协程对象,Future,Task对象)
await是一个只能在协程函数中使用的关键字,用于遇到IO操作时挂起 当前协程(任务),当前协程(任务)挂起过程中 事件循环可以去执行其他的协程(任务),当前协程IO处理完成时,可以再次切换回来执行await之后的代码。

import asyncio
async def func():
    print("执行协程函数内部代码")
    # 遇到IO操作挂起当前协程(任务),等IO操作完成之后再继续往下执行。
    # 当前协程挂起时,事件循环可以去执行其他协程(任务)。
	#response是IO耗时结束后拿到的结果
    response = await asyncio.sleep(2)
    print("IO请求结束,结果为:", response)
result = func()
asyncio.run(result)

结果
执行协程函数内部代码
IO请求结束,结果为: None
#这里返回None表示这个好事没有啥意义,如果你是下载了一张图片成功后会返回一个结果

示例2:

import asyncio
async def others():
    print("start")
    await asyncio.sleep(2)
    print('end')
    return '返回值'
async def func():
    print("执行协程函数内部代码")
    # 遇到IO操作挂起当前协程(任务),等IO操作完成之后再继续往下执行。当前协程挂起时,事件循环可以去执行其他协程(任务)。
    response = await others()
    print("IO请求结束,结果为:", response)
asyncio.run( func() )

执行结果:
执行协程函数内部代码
start
end
IO请求结束,结果为: 返回值

示例3:

import asyncio
async def others():
    print("start")
    await asyncio.sleep(2)
    print('end')
    return '返回值'
async def func():
    print("执行协程函数内部代码")
    # 遇到IO操作挂起当前协程(任务),等IO操作完成之后再继续往下执行。当前协程挂起时,事件循环可以去执行其他协程(任务)。
    #await等待有返回值才会向下执行
    response1 = await others()
    print("IO请求结束,结果为:", response1)
    response2 = await others()
    print("IO请求结束,结果为:", response2)
asyncio.run( func() )

执行结果:
执行协程函数内部代码
start
end
IO请求结束,结果为: 返回值
start
end
IO请求结束,结果为: 返回值

下一步依赖上一步的结果时使用await,但如果有其他任务依然会切换到其他任务去执行

2.3 Task对象

在事件循环中添加多个任务。
Tasks用于并发调度协程,通过asyncio.create_task(协程对象)的方式创建Task对象,这样可以让协程加入事件循环中等待被调度执行。

除了使用 asyncio.create_task() 函数以外,还可以用低层级的 loop.create_task() 或 ensure_future() 函数。

不建议手动实例化 Task 对象。

本质上是将协程对象封装成task对象,并将协程立即加入事件循环,同时追踪协程的状态。
注意:asyncio.create_task() 函数在 Python 3.7 中被加入。

在 Python 3.7 之前,可以改用低层级的 asyncio.ensure_future() 函数。

示例1:

import asyncio
async def func():
    print(1)
    await asyncio.sleep(2)
    print(2)
    return "返回值"
async def main():
    print("main开始")
    # 创建协程,将协程封装到一个Task对象中并立即添加到事件循环的任务列表中,等待事件循环去执行(默认是就绪状态)。
    task1 = asyncio.create_task(func())
    # 创建协程,将协程封装到一个Task对象中并立即添加到事件循环的任务列表中,等待事件循环去执行(默认是就绪状态)。
    task2 = asyncio.create_task(func())
    print("main结束")
    # 当执行某协程遇到IO操作时,会自动化切换执行其他任务。
    # 此处的await是等待相对应的协程全都执行完毕并获取结果
    ret1 = await task1
    ret2 = await task2
    print(ret1, ret2)
asyncio.run(main())

执行结果:
main开始
main结束
1
1
2
2
返回值 返回值

实例2:

import asyncio
async def func():
    print(1)
    await asyncio.sleep(2)
    print(2)
    return "返回值"
async def main():
    print("main开始")
    # 创建协程,将协程封装到Task对象中并添加到事件循环的任务列表中,等待事件循环去执行(默认是就绪状态)。
    # 在调用
    task_list = [
        asyncio.create_task(func(), name="n1"),
        asyncio.create_task(func(), name="n2")
    ]
    print("main结束")
    # 当执行某协程遇到IO操作时,会自动化切换执行其他任务。
    # 此处的await是等待所有协程执行完毕,并将所有协程的返回值保存到done
    # 如果设置了timeout值,则意味着此处最多等待的秒,完成的协程返回值写入到done中,未完成则写到pending中(比如下面的Timeout=1,要下载的图片是两秒,设为1秒就会执行失败,done内为空,而pending中就是执行失败的)。
    done, pending = await asyncio.wait(task_list, timeout=None)
    print(done, pending)
asyncio.run(main())

执行结果:
main开始
main结束
1
1
2
2
{
   <Task finished name='n1' coro=<func() done, defined at C:/Users/xuan.li/Desktop/unidevopss/py3x64/ibuildmaster/apps/PROD/tests.py:513> result='返回值'>,
   <Task finished name='n2' coro=<func() done, defined at C:/Users/xuan.li/Desktop/unidevopss/py3x64/ibuildmaster/apps/PROD/tests.py:513> result='返回值'>
}
 set()

示例3:

import asyncio
async def func():
    print("执行协程函数内部代码")
    # 遇到IO操作挂起当前协程(任务),等IO操作完成之后再继续往下执行。当前协程挂起时,事件循环可以去执行其他协程(任务)。
    response = await asyncio.sleep(2)
    print("IO请求结束,结果为:", response)
coroutine_list = [func(), func()]
# 错误:coroutine_list = [ asyncio.create_task(func()), asyncio.create_task(func()) ]
# 此处不能直接 asyncio.create_task,因为将Task立即加入到事件循环的任务列表,
# 但此时事件循环还未创建,所以会报错。
# 使用asyncio.wait将列表封装为一个协程,并调用asyncio.run实现执行两个协程
# asyncio.wait内部会对列表中的每个协程执行ensure_future,封装为Task对象。
done,pending = asyncio.run( asyncio.wait(coroutine_list) )

以上就是Python协程asyncio 异步编程笔记分享的详细内容,更多关于Python协程asyncio 异步编程的资料请关注我们其它相关文章!

(0)

相关推荐

  • asyncio 的 coroutine对象 与 Future对象使用指南

    coroutine 与 Future 的关系 看起来两者是一样的,因为都可以用以下的语法来异步获取结果, result = await future result = await coroutine 实际上,coroutine 是生成器函数,它既可以从外部接受参数,也可以产生结果.使用 coroutine 的好处是,我们可以暂停一个函数,然后稍后恢复执行.比如在涉及到网路操作的情况下,能够停下函数直到响应到来.在停下的这段时间内,我们可以切换到其他任务继续执行. 而 Future 更像是 Jav

  • 详解python异步编程之asyncio(百万并发)

    前言:python由于GIL(全局锁)的存在,不能发挥多核的优势,其性能一直饱受诟病.然而在IO密集型的网络编程里,异步处理比同步处理能提升成百上千倍的效率,弥补了python性能方面的短板,如最新的微服务框架japronto,resquests per second可达百万级. python还有一个优势是库(第三方库)极为丰富,运用十分方便.asyncio是python3.4版本引入到标准库,python2x没有加这个库,毕竟python3x才是未来啊,哈哈!python3.5又加入了asyn

  • python中asyncio异步编程学习

    1.   想学asyncio,得先了解协程 携程的意义: 计算型的操作,利用协程来回切换执行,没有任何意义,来回切换并保存状态 反倒会降低性能. IO型的操作,利用协程在IO等待时间就去切换执行其他任务,当IO操作结束后再自动回调,那么就会大大节省资源并提供性能,从而实现异步编程(不等待任务结束就可以去执行其他代码 2.协程和多线程之间的共同点和区别: 共同点: 都是并发操作,多线程同一时间点只能有一个线程在执行,协程同一时间点只能有一个任务在执行: 不同点: 多线程,是在I/O阻塞时通过切换线

  • python 使用事件对象asyncio.Event来同步协程的操作

    事件对象asyncio.Event是基于threading.Event来实现的. 事件可以一个信号触发多个协程同步工作, 例子如下: import asyncio import functools def set_event(event): print('setting event in callback') event.set() async def coro1(event): print('coro1 waiting for event') await event.wait() print(

  • asyncio异步编程之Task对象详解

    目录 1.Task对象的作用 2.如何创建task对象 3.示例一(目前不推荐这种写法) 4.示例2 5.示例3(算是以上示例2的简化版) 总结 1.Task对象的作用 可以将多个任务添加到事件循环当中,达到多任务并发的效果 2.如何创建task对象 asyncio.create_task(协程对象) 注意:create_task只有在python3.7及以后的版本中才可以使用,就像asyncio.run()一样, 在3.7以前可以使用asyncio.ensure_future()方式创建tas

  • Python协程asyncio 异步编程笔记分享

    目录 1.事件循环 2.协程和异步编程 2.1 基本使用 2.2 await 2.3 Task对象 1.事件循环 可以理解成为一个死循环,去检查任务列表中的任务,如果可执行就去执行,如果检查不到就是不可执行的,那就忽略掉去执行其他可执行的任务,如果IO结束了(比如说去百度下载图片,下载完了就会变成可执行任务)再去执行下载完成之后的逻辑 #这里的任务是有状态的,比如这个任务已经完成或者正在执行或者正在IO等待 任务列表 = [ 任务1, 任务2, 任务3,... ] while True: 可执行

  • Python协程asyncio异步编程笔记分享

    目录 1.事件循环 2.协程和异步编程 2.1基本使用 2.2await 2.3Task对象 1.事件循环 可以理解成为一个死循环,去检查任务列表中的任务,如果可执行就去执行,如果检查不到就是不可执行的,那就忽略掉去执行其他可执行的任务,如果IO结束了(比如说去百度下载图片,下载完了就会变成可执行任务)再去执行下载完成之后的逻辑 #这里的任务是有状态的,比如这个任务已经完成或者正在执行或者正在IO等待 任务列表 = [ 任务1, 任务2, 任务3,... ] while True: 可执行的任务

  • Python协程asyncio模块的演变及高级用法

    Python协程及asyncio基础知识 协程(coroutine)也叫微线程,是实现多任务的另一种方式,是比线程更小的执行单元,一般运行在单进程和单线程上.因为它自带CPU的上下文,它可以通过简单的事件循环切换任务,比进程和线程的切换效率更高,这是因为进程和线程的切换由操作系统进行. Python实现协程的主要借助于两个库:asyncio和gevent.由于asyncio已经成为python的标准库了无需pip安装即可使用,这意味着asyncio作为Python原生的协程实现方式会更加流行.本

  • 浅谈Python协程asyncio

    一.协程 官方描述; 协程是子例程的更一般形式. 子例程可以在某一点进入并在另一点退出. 协程则可以在许多不同的点上进入.退出和恢复. 它们可通过 async def 语句来实现. 参见 PEP 492. 协程不是计算机内部提供的,不像进程.线程,由电脑本身提供,它是由程序员人为创造的, 实现函数异步执行. 协程(Coroutine),也可以被称为微线程,是一种用户太内的上下文切换技术,其实就是通过一个线程实现代码块相互切换执行.看上去像子程序,但执行过程中,在子程序内部可中断,然后转而执行别的

  • Python协程方式的实现及意义笔记分享

    目录 协程 1.greenlet实现协程 2.yield 3.asyncio 4.async & awit 2.协程的意义 小结 协程 协程不是计算机提供的,是程序员认为创造 协程也被称为微线程,是一种用户态的上下文切换技术,简而言之,就是通过一个线程实现代码互相切换执行 实现协程的几种方法: 1)greenlet,早期模块 2)yield关键字 3)asyncio装饰器 (python3.4以后引入的) 4)async,await关键字 (python3.5) 推荐 1.greenlet实现协

  • python 中的 asyncio 异步协程

    目录 一.定义协程 二.运行协程 三.协程回调 四.运行多个协程 五.run_forever 六.多协程中关闭run_forever 一.定义协程 asyncio 执行的任务,称为协程,但是Asyncio 并不能带来真正的并行 Python 的多线程因为 GIL(全局解释器锁)的存在,也不能带来真正的并行 import asyncio # 通过 async 定义一个协程 async def task(): print('这是一个协程') # 判断是否是一个协程,返回True print(asyn

  • Python协程实践分享

    目录 协程 yield在协程中的用法 经典示例 生产者-消费者模式(协程) gevent第三方库协程支持 经典代码 asyncio内置库协程支持 关于aiohttp 协程 协程简单来说就是一个更加轻量级的线程,并且不由操作系统内核管理,完全由程序所控制(在用户态执行).协程在子程序内部是可中断的,然后转而执行其他子程序,在适当的时候返回过来继续执行. 协程的优势?(协程拥有自己的寄存器上下文和栈,调度切换时,寄存器上下文和栈保存到其他地方,在切换回来的时候,恢复先前保存的寄存器上下文和栈,直接操

  • Python asyncio异步编程简单实现示例

    目录 一.asyncio事件循环简介 二.async协程函数简介 三.await关键字 四.async异步编程简单实现 今天继续给大家介绍Python相关知识,本文主要内容是Python asyncio异步编程简单实现. 一.asyncio事件循环简介 asyncio引入了事件循环的概念.事件循环是一个死循环,还循环会检测并执行某些代码.在Python中,引入了asyncio模块后,执行命令: loop=asyncio.get_event_loop() 可以生成一个事件循环,而执行命令: loo

  • Python asyncio异步编程常见问题小结

    目录 一.asyncio编程简单示例 二.asyncio编程常见问题 三.报错原因及解决方案 今天继续给大家介绍Python相关知识,本文主要内容是Python asyncio异步编程常见问题. 一.asyncio编程简单示例 首先,我们来看一段简单的Python asyncio异步编程代码,相关代码如下所示: import asyncio async def fun(): print(1) await asyncio.sleep(2) print(2) return 3 async def m

随机推荐