当前位置: 首页 > article >正文

asyncio教程

简介

asyncio是一种使用单线程单进程的的方式实现并发的工具。asyncio提供的框架以事件循环(event loop)为中心,程序开启一个无限的循环,程序会把一些函数注册到事件循环上。当满足事件发生的时候,调用相应的协程函数。

event loop

Eventloop实例提供了注册、取消和执行任务(Task)和回调的方法。

把一些异步函数注册到这个事件循环上,事件循环会循环执行这些函数(但同时只能执行一个),当执行到某个函数时,如果它正在等待I/O返回,事件循环会暂停它的执行去执行其他的函数;当某个函数完成I/O后,会恢复下次循环到它的时候继续执行。因此,这些异步函数可以协同(Cooperative)运行

协程(Coroutine)

协程本质上是一个函数,特点是在代码块中可以将执行权交给其他协程。

import asyncio

async def a():#async定义协程
    print('Suspending a')
    await asyncio.sleep(0)#await表示调用协程,sleep 0并不会真的sleep,但却交出控制权
    print('Resuming a')

async def b():
    print('In b')

async def main():
    await asyncio.gather(a(), b())#并发运行任务,在这里表示协同的执行a和b两个协程

if __name__ == '__main__':
    asyncio.run(main())
#运行结果:表示在运行协程a的过程中让出了控制权,并发执行协程b,之后再返回执行a
#Suspending a
#In b
#Resuming a

Future

future是一个数据结构,表示还未完成的工作结果。事件循环可以监视Future对象是否完成。从而允许一个协程等待另一协程完成一些工作

Task

Task是Future的一个子类,它知道如何包装和管理一个协程的执行。任务所需的资源可用时,事件循环会调度任务允许,并生成一个结果,从而可以由其他协程消费。

task = asyncio.ensure_future(a())
#或者是task = loop.create_task(a())
print(task.done())#False
await task#真正开始执行
print(task.done())#True

执行协程的例子

#下面是一个错误的例子
import asyncio
import time

async def say_after(delay, what):#定义了一个协程函数
    await asyncio.sleep(delay)
    print(what)

async def main():#同样也是协程
    print(f"started at {time.strftime('%X')}")

    await say_after(1, 'hello')#顺序执行两个协程
    await say_after(2, 'world')

    print(f"finished at {time.strftime('%X')}")

asyncio.run(main())
#结果是并没有实现两个协程并发执行,因为等待的时间有3s
async def main():#惯用写法是在协程main中执行其他的协程
    task1 = asyncio.create_task(#将协程函数用Task封装
        say_after(1, 'hello'))

    task2 = asyncio.create_task(
        say_after(2, 'world'))

    print(f"started at {time.strftime('%X')}")

    # Wait until both tasks are completed (should take
    # around 2 seconds.)
    await task1#也是顺序执行两个协程
    await task2

    print(f"finished at {time.strftime('%X')}")
#结果是真正实现了两个协程的并发执行,因为执等待了2s
#注意错误的写法,下面的不能实现协程的并发执行
#await asyncio.create_task(say_after(1, 'hello'))
#await asyncio.create_task(say_after(2, 'world'))
#使用下面的形式也可以实现协程的并发执行
async def main():
    await asyncio.gather(say_after(1, 'hello'), say_after(2, 'world'))
async def main():
    await asyncio.wait([say_after(1, 'hello'), say_after(2, 'world')])

可等待对象await

可以在await语句中使用的对象,有三种协程,Future和Task,只是通常情况下没有必要在应用代码中创建 Future 对象。

import asyncio

async def nested():
    return 42

async def main():
    nested()#此协程并没有执行
    print(await nested()) #使用await才会真正执行

asyncio.run(main())
import asyncio

async def nested():
    return 42

async def main():
    task = asyncio.create_task(nested())
    await task

asyncio.run(main())

函数签名

coroutine asyncio.sleep(delay, result=None)
#阻塞 delay 秒,如果指定了 result,则当协程完成时将其返回给调用者。
#sleep() 总是会挂起当前任务,以允许其他任务运行。
#将 delay 设为 0 将提供一个经优化的路径以允许其他任务运行。 这可供长期间运行的函数使用以避免在函数调用的全过程中阻塞事件循环。


http://www.kler.cn/a/104804.html

相关文章:

  • 【目标检测】非极大值抑制NMS的原理与实现
  • C/C++输出整数 2020年9月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析
  • 记录nvm use node.js版本失败,出现报错: exit status 1: ��û���㹻��Ȩ��ִ�д˲�����
  • 群面的技巧
  • 如何实现两栏布局?这篇文章告诉你所有的细节!
  • influxdb基本使用及其源码解析
  • Ubuntu 安装 npm 和 node
  • RabbitMQ原理(四):MQ的可靠性
  • 【linux】SourceForge 开源软件开发平台和仓库
  • 云游数智农业世界,体验北斗时空智能
  • 什么是web3.0?
  • 基于STM32+物联网设计的货车重量检测系统(OneNet)
  • 如何通过企业培训考试系统实现持续学习和发展
  • RabbitMQ的交换机(原理及代码实现)
  • PPT文档图片设计素材资源下载站模板源码/织梦内核(带用户中心+VIP充值系统+安装教程)
  • 【凡人修仙传】定档,四女神出场,韩立遭极阴岛陷阱,蛮胡子亮相
  • kvm webvirtcloud 如何添加直通物理机的 USB 启动U盘
  • Kotlin(八) 数据类、单例
  • 【QML】ListView 报错 ReferenceError: index is not defined
  • CSP-J2023入门组第二轮T4:旅游巴士