asyncio的简单了解
asyncio
是Python 3.4版本引入的标准库,直接内置了对异步IO的支持。
asyncio
的编程模型就是一个消息循环。我们从asyncio
模块中直接获取一个EventLoop
的引用,然后把需要执行的协程扔到EventLoop
中执行,就实现了异步IO。
用asyncio
实现Hello world
代码如下:
import asyncio @asyncio.coroutine
def hello():
print("Hello world!")
# 异步调用asyncio.sleep(1):
r = yield from asyncio.sleep(1)
print("Hello again!") # 获取EventLoop:
loop = asyncio.get_event_loop()
# 执行coroutine
loop.run_until_complete(hello())
loop.close()
关于asyncio的一些关键字的说明:
event_loop 事件循环:程序开启一个无限循环,把一些函数注册到事件循环上,当满足事件发生的时候,调用相应的协程函数
coroutine 协程:协程对象,指一个使用async关键字定义的函数,它的调用不会立即执行函数,而是会返回一个协程对象。协程对象需要注册到事件循环,由事件循环调用。
task 任务:一个协程对象就是一个原生可以挂起的函数,任务则是对协程进一步封装,其中包含了任务的各种状态
future: 代表将来执行或没有执行的任务的结果。它和task上没有本质上的区别
async/await 关键字:python3.5用于定义协程的关键字,async定义一个协程,await用于挂起阻塞的异步调用接口。
一个最基本的示例:
import time
import asyncio now = lambda :time.time() print(now) # <function <lambda> at 0x000001F6E1E52E18> 相信部分人到这就蒙圈了吧,lambda还能这么用
start = now() async def do_some_work(x):
print("waiting:",x) coroutine = do_some_work(10) print(coroutine) # <coroutine object do_some_work at 0x000002133DEFBAF0> 一个协程对象 # 创建一个事件loop
loop = asyncio.get_event_loop() # 将携程对象加入到事件循环loop中
loop.run_until_complete(coroutine) print("Use Time:",now()-start)
备注:
1、我们通过async关键字定义一个协程(coroutine),当然这个协程不能直接运行,需要将协程加入到事件循环loop中
2、asyncio.get_event_loop:创建一个事件循环,然后使用run_until_complete将协程注册到事件循环,并启动事件循环
创建Task
协程对象注册到事件循环loop中,是通过run_until_complete 方法实现的,其实这个run_until_complete方法内部是将协程包装成为了一个任务(task)对象。
这个 task对象是Future类的子类,它保存了协程运行后的状态,用来后续获取协程的结果
示例:
import asyncio
import time now = lambda: time.time() async def do_some_work(x):
print("waiting:", x) start = now() coroutine = do_some_work(2)
loop = asyncio.get_event_loop()
# 创建一个task对象
task = loop.create_task(coroutine)
print(task,type(task)) # <Task pending coro=<do_some_work() running at D:/webserver/unittests/async.py:8>> <class '_asyncio.Task'>
loop.run_until_complete(task)
print(task) # <Task finished coro=<do_some_work() done, defined at D:/webserver/unittests/async.py:8> result=None>
print("Time:",now()-start)
由此示例可见: 在task加入事件循环之前为pending状态,当完成后,状态为finished
扩展补充:
上面的示例中,我们通过loop.create_task() 来创建一个task,同样的,我们也可以使用 asyncio.ensure_future(coroutine) 来创建task
总结:
1,异步操作需要在coroutine
中通过yield from
完成
asyncio的简单了解的更多相关文章
- Python 原生协程------asyncio
协程 在python3.5以前,写成的实现都是通过生成器的yield from原理实现的, 这样实现的缺点是代码看起来会很乱,于是3.5版本之后python实现了原生的协程,并且引入了async和aw ...
- Python 异步编程笔记:asyncio
个人笔记,不保证正确. 虽然说看到很多人不看好 asyncio,但是这个东西还是必须学的.. 基于协程的异步,在很多语言中都有,学会了 Python 的,就一通百通. 一.生成器 generator ...
- python3.x 多路IO复用补充asyncio
asyncio模块是python之父写的模块,按说应该是靠谱的,python3.6版本定义为稳定版本. 说明书:https://docs.python.org/3/library/asyncio.ht ...
- 一个使用 asyncio 开发的网络爬虫(译文)
原文地址:https://www.aosabook.org/en/500L/a-web-crawler-with-asyncio-coroutines.html 作者简介 A. Jesse Jiryu ...
- Gevent模块
前言 如何在使用1个线程的前提下,提网站的并发性,使用协程? 如果要使用协程首先要解决2个问题: 1.如何检测到代码中遇到了IO操作?(XX) 2.如何在线程代码里上下切换?(Greelet模块) 而 ...
- 异步编程之asyncio简单介绍
引言: python由于GIL(全局锁)的存在,不能发挥多核的优势,其性能一直饱受诟病.然而在IO密集型的网络编程里,异步处理比同步处理能提升成百上千倍的效率,弥补了python性能方面的短板. as ...
- Python标准模块--asyncio
1 模块简介 asyncio模块作为一个临时的库,在Python 3.4版本中加入.这意味着,asyncio模块可能做不到向后兼容甚至在后续的Python版本中被删除.根据Python官方文档,asy ...
- 从零构建一个简单的 Python Web框架
为什么你想要自己构建一个 web 框架呢?我想,原因有以下几点: 你有一个新奇的想法,觉得将会取代其他的框架 你想要获得一些名气 你遇到的问题很独特,以至于现有的框架不太合适 你对 web 框架是如何 ...
- Python asyncio库的学习和使用
因为要找工作,把之前自己搞的爬虫整理一下,没有项目经验真蛋疼,只能做这种水的不行的东西...T T,希望找工作能有好结果. 之前爬虫使用的是requests+多线程/多进程,后来随着前几天的深入了解 ...
随机推荐
- RHEL 7中有关终端的快捷方式
快速启动终端 网上有不错的教程,只是有时候和版本有一定的出入,这里涉及小白博主自行摸索的过程(RHEL 7.4). 1.点击桌面右上角,选择设置(小扳手) 2.选择键盘(Keyboard) 3.将进度 ...
- 洛谷 U14475 部落冲突 【比赛】 【树链剖分 + 线段树】
题目背景 在一个叫做Travian的世界里,生活着各个大大小小的部落.其中最为强大的是罗马.高卢和日耳曼.他们之间为了争夺资源和土地,进行了无数次的战斗.期间诞生了众多家喻户晓的英雄人物,也留下了许多 ...
- 【Django实例】博客1
(上一篇) 一.概述 Blog是一个博客应用. dbe工程的目录结构,参考<序言>的最后部分.blog应用位于/home/russellluo/Django/dbe/dbe/blog目录下 ...
- 解题:BOI 2008 Elect
题面 做背包时可以通过排序来使得转移满足某种限制或是让我们判断一个状态是否有贡献 这个题将人数从大到小排序后做背包,这样每次那个最小的党加入而使得答案合法时之前的党也都是合法的 #include< ...
- struts2初探(一)
首先需要了解Struts2框架的运行过程: request从发送到服务器,即tomcat,然后tomcat参考web.xml,发现所有的url都需要经过struts2的过滤, Struts2调用dof ...
- selenium - webdriver - 定位一组元素
八种方法: find_elements_by_id() find_elements_by_name() find_elements_by_class_name() find_elements_by_t ...
- Qt ------ 再论事件循环
在介绍在以前,我们要认识两个术语: 可重入的(Reentrant):如果多个线程可以在同一时刻调用一个类的所有函数,并且保证每一次函数调用都引用一个唯一的数据,就称这个类是可重入的(Reentrant ...
- ubuntu 安装部分设置U盘启动系统安装盘操作
https://jingyan.baidu.com/article/6079ad0ec4925728ff86db02.html 第三种方法适合新机型,在启动时按F10或F11,可直接选择启动模式 -- ...
- Tensorboard教程:Tensorflow命名空间与计算图可视化
Tensorflow命名空间与计算图可视化 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 强烈推荐Tensorflow实战Google深度学习框架 实验平台: Tensorflow ...
- Android 加载网络图片设置到ImageView
下载图片后显示在ImageView中 //1.定义全局变量 private Handler handler; private String image_url; private Bitmap bitm ...