Python 3.8 Asyncio - Asynchronous I/O 异步教程

本文适用于python 3.8

3.8版本更新去掉了几个函数的loop参数,以及一些函数的修改增强了可读性。

这是我的学习笔记,如有错误请多加指正。

天勤量化核心用的是asyncio,可以是金融行业一个很好的应用。我认为asyncio的优势是简化异步回调。将一个异步的架构转化成同步。代码量可以减少,更好想一些。 而且python本身有GIL的原因,本质是一个单线程的。 用多线程的思路写python没有意义。 我对于asyncio的形象理解是:如果你跑得足够快,一个人所有事情都可以飞速搞定,不需要等待。比如闪电侠做饭:买菜,烧水,切菜,炒菜,端菜都可以不间断的安排上。 多线程就好比你安排好几个人同时去买菜,烧水,切菜,炒菜,端菜。

还有一个协程的应用是pysimpleGUI。虽然pysimgpleGUI没有用到asyncio,思想是协程的思想,即用event loop替代callback function。简化了GUI创作的代码量。

关键概念

同步和异步

async/await

协程对象,协程函数

Awaitables: coroutinue, task, future

Event Loop

什么是asyncio?

Asyncio,即Asynchronous I/O是python一个用来处理并发(concurrent)事件的包,通过asnyc/await来表达, 是目前很多python异步架构的基础,多用作高性能网络处理方面,很容易解决了IO-bound的问题。

什么是协程 Coroutine?

协程是一种用户态的轻量级线程,不同于线程。 每一个协程可以暂时挂起以便其他协程开始工作。 当一个协程在等待网络请求时,我们可以把他挂起然后去做其他的事情。

协程系统需要具备管理何时挂起不同的协程以及运行需要的协程。 这个架构多半是通过event loop实现的。

协程函数(coroutine function)是通过async/await标识的特殊函数。

协程对象(coroutine object)是协程函数返回的对象object。

协程函数区别于普通函数,不能直接运行,而需要通过asyncio封装的函数运行。协程的异步是通过event loop实现的。 协程函数可以嵌套。

import asyncio

async def inner_coro(): # 定义

return "Hello World"

async def main():

message = await inner_coro()

print(message)

result = asyncio.run(main()) # main()本身是一个协程

print(result)

运行协程的三种基本方式

async.run()

async.create_task()

async.gather()

1. 用asyncio.runners 运行最简单的协程函数:

asyncio.run(coro): 作为 top-level entry point "main()" function。封装了生成event loop,结果获取,结束时自己关闭event loop。 如果当前线程有event loop运行,则不能运行。

import asyncio

import time

async def main():

print("start doing some work.")

await asyncio.sleep(5)

print("work is done.")

return 0

start = time.time()

result = asyncio.run(main())

print(result)

now = time.time()

print("Run Time:", now - start)

2. asyncio.create_task(coro) -> Task

通过asyncio.create_task计划协程任务。

在调用main()之前,先把Tasks建好,然后一起运行会达到协程的效果。

对比两个不同的写法:

import asyncio

import time

async def say_after(delay, what):

await asyncio.sleep(delay)

return what

async def main():

task1 = asyncio.create_task(

say_after(1, 'hello'))

task2 = asyncio.create_task(

say_after(2, 'world'))

start = time.time()

await task1

await task2

now = time.time()

print("Time Consumed: ", now - start)

asyncio.run(main()) # 总共需要2秒

import asyncio

import time

async def say_after(delay, what):

await asyncio.sleep(delay)

return what

async def main():

start = time.time()

await say_after(1,"hello")

await say_after(2,"world")

now = time.time()

print("Time Consumed: ", now - start)

asyncio.run(main()) # 总共需要3秒

第二个写法需要三秒的原因是因为程序按顺序执行了say_after(1,"hello")和say_after(2,"world")。没有达到并发的效果。

3. asyncio.gather(*aws) -> results

import asyncio

import time

async def say_after(delay, what):

await asyncio.sleep(delay)

return what

async def main():

start = time.time()

task1 = say_after(1,"hello")

task2 = say_after(2,"world")

message = await asyncio.gather(task1, task2)

print(message)

now = time.time()

print("Time Consumed: ", now - start)

asyncio.run(main()) # 总共需要2秒

三种可以被挂起的对象 Awaitable objects

coroutines

Tasks

Futures

这三种object都可以被挂起。

协程是可挂起的。挂起后的协程就是协程的嵌套。

1. Coroutines

见上文

2. Tasks

Tasks are used to schedule coroutines concurrently. Tasks的作用是计划安排协程。

3. Futures

A Future is a special low-level awaitable object that represents an eventual result of an asynchronous operation.

Future的作用是用来绑定回调。通常我们不需要建立Future。

import time

import asyncio

now = lambda : time.time()

async def do_some_work(x):

print('Waiting: ', x)

return 'Done after {}s'.format(x)

def callback(future):

print('Callback: ', future.result())

start = now()

coroutine = do_some_work(2)

loop = asyncio.get_event_loop()

task = asyncio.ensure_future(coroutine)

task.add_done_callback(callback)

loop.run_until_complete(task)

print('TIME: ', now() - start)

用functools定义回调函数参数

def callback(t, future):

print('Callback:', t, future.result())

task.add_done_callback(functools.partial(callback, 2))

常用函数

asyncio.sleep(delay, result = None, *)

asyncio.gather(*aws, loop = None, return_exceptions = False)->aw

asyncio.shield(aw,*)

asyncio.wait_for(aw, timeout, *)

Cancel the futures when a timeout occurs.

asyncio.as_completed(aws,*,timeout = None)

Run awaitable objects in the aws set concurrently. Return an iterator of coroutines.

Scheduling from other threads

asyncio.current_task(loop=None)

If loop is None,get the current loop.

asyncio.all_tasks(loop = None)

References

python asyncio教程_Python Asyncio 教程相关推荐

  1. python图纸教程_python入门教程 python入门神图一张

    初试牛刀 假设你希望学习Python这门语言,却苦于找不到一个简短而全面的入门教程.那么本教程将花费十分钟的时间带你走入Python的大门.本文的内容介于教程(Toturial)和速查手册(Cheat ...

  2. python 3教程_Python 3 教程

    全屏 Python 3 教程 Python的3.0版本,常被称为Python 3000,或简称Py3k.相对于Python的早期版本,这是一个较大的升级.为了不带入过多的累赘,Python 3.0在设 ...

  3. python独立网站教程_python做网站教程_如何免费做网站的教程

    python学习指南教程 180x270 - 7KB - JPEG 图灵程序设计丛书:Python基础教程 260x317 - 12KB - JPEG 跳一跳python使用教程 微信跳一跳pytho ...

  4. python画四边形_python绘图教程-用python来绘制出四边形

    原标题:python绘图教程-用python来绘制出四边形 python的应用有很多,其中还可以用python来绘制四边形,下面羽忆教程网为您分享如何用python来绘制四边形的详细步骤. pytho ...

  5. python 优雅退出_Python学习教程:Python 使用 backoff 更优雅的实现轮询

    我们经常在开发中会遇到这样一种场景,即轮循操作.今天介绍一个Python库,用于更方便的达到轮循的效果--backoff. Python学习教程:Python 使用 backoff 更优雅的实现轮询 ...

  6. python 包用法_Python 基础教程之包和类的用法

    Python 基础教程之包和类的用法 这篇文章主要介绍了 Python 基础教程之包和类的用法的相关资料, 需要的朋友可以参考下 Python 是一种面向对象.解释型计算机程序设计语言,由 Guido ...

  7. python爬虫scrapy框架教程_Python爬虫教程-30-Scrapy 爬虫框架介绍

    从本篇开始学习 Scrapy 爬虫框架 Python爬虫教程-30-Scrapy 爬虫框架介绍 框架:框架就是对于相同的相似的部分,代码做到不出错,而我们就可以将注意力放到我们自己的部分了 常见爬虫框 ...

  8. python requests模块_Python 爬虫教程 requests 模块

    经过 前边文章<简单Python爬虫教程 (一)>.简单Python爬虫教程 (二)两篇文章的学习,能写一些比较简单的爬虫了,但是还不够,这一篇文章主要介绍Requests模块,reque ...

  9. python模块编程教程_python进阶教程之模块(module)介绍

    我们之前看到了函数和对象.从本质上来说,它们都是为了更好的组织已经有的程序,以方便重复利用. 模块(module)也是为了同样的目的.在Python中,一个.py文件就构成一个模块.通过模块,你可以调 ...

最新文章

  1. Java项目:在线蛋糕商城系统(java+jsp+jdbc+mysql)
  2. GridView控件添加鼠标移入移出时背景行变色的效果
  3. 属性名_CSS -- 属性选择器
  4. C#访问MySQL数据库的方法
  5. 网骗欺诈?网络裸奔?都是因为 HTTP?
  6. 后台如何通过Request取得多个含有相同name的控件的值?
  7. 根据数据库表gengxin实体类_ASP.NET开发实战——(十二)数据库之EF Migrations
  8. 两台服务器建立信任关系(root,普通用户)
  9. python groupby用法_Python数据分析黑色星期五-知识点整理
  10. 线材下料优化python算法_深度学习中的优化算法(Optimizer)理解与python实现
  11. 办公必备APP,收藏有料
  12. 机器学习 - 训练集、验证集、测试集
  13. 3K热敏电阻测温程序
  14. MMA7455加速度传感器测量角度
  15. Linux IP代理筛选系统(shell+proxy)
  16. INDEMIND:多传感器融合,机器人的必由之路
  17. 抖音做我女朋友的 vbs 脚本
  18. 那些有趣的网站系列(十)
  19. 在线考试防作弊js代码
  20. 计算机专业就业推荐表中求职意愿,毕业生推荐表的求职意愿怎么填啊?

热门文章

  1. 上交所FAST行情接口对接
  2. uni-app 阉割版的vue uni-app开发中的小坑。
  3. MySQL基础---连接查询(等值连接与非等值连接)
  4. 1N4148WS-E3-08你不得不知道的二三事
  5. 常用CMOS模拟开关功能和原理
  6. 元宇宙暗藏的十大风险
  7. FreeRTOS互斥量 基于STM32
  8. sorl的全量更新与增量更新
  9. 2023华为od机试真题【简易内存池】C语言
  10. html 文本框回车触发按钮点击事件