python 并发专题(十三):asyncio (一) 初识
https://www.cnblogs.com/wongbingming/p/9095243.html
. 本文目录#
- 如何定义/创建协程
- asyncio的几个概念
- 学习协程是如何工作的
- await与yield对比
- 绑定回调函数
. 如何定义/创建协程#
只要在一个函数前面加上 async 关键字,这个函数对象是一个协程,通过isinstance函数,它确实是Coroutine类型。
from collections.abc import Coroutine async def hello(name):
print('Hello,', name) if __name__ == '__main__':
# 生成协程对象,并不会运行函数内的代码
coroutine = hello("World") # 检查是否是协程 Coroutine 类型
print(isinstance(coroutine, Coroutine)) # True
生成器是协程的基础,那我们是不是有办法,将一个生成器,直接变成协程使用
import asyncio
from collections.abc import Generator, Coroutine '''
只要在一个生成器函数头部用上 @asyncio.coroutine 装饰器
就能将这个函数对象,【标记】为协程对象。注意这里是【标记】,划重点。
实际上,它的本质还是一个生成器。
标记后,它实际上已经可以当成协程使用。后面会介绍。
''' @asyncio.coroutine
def hello():
# 异步调用asyncio.sleep(1):
yield from asyncio.sleep(1) if __name__ == '__main__':
coroutine = hello()
print(isinstance(coroutine, Generator)) # True
print(isinstance(coroutine, Coroutine)) # False
asyncio的几个概念#
在了解asyncio的使用方法前,首先有必要先介绍一下,这几个贯穿始终的概念。
event_loop 事件循环:程序开启一个无限的循环,程序员会把一些函数(协程)注册到事件循环上。当满足事件发生的时候,调用相应的协程函数。coroutine 协程:协程对象,指一个使用async关键字定义的函数,它的调用不会立即执行函数,而是会返回一个协程对象。协程对象需要注册到事件循环,由事件循环调用。future 对象: 代表将来执行或没有执行的任务的结果。它和task上没有本质的区别task 任务:一个协程对象就是一个原生可以挂起的函数,任务则是对协程进一步封装,其中包含任务的各种状态。Task 对象是 Future 的子类,它将 coroutine 和 Future 联系在一起,将 coroutine 封装成一个 Future 对象。async/await 关键字:python3.5 用于定义协程的关键字,async定义一个协程,await用于挂起阻塞的异步调用接口。其作用在一定程度上类似于yield。
这几个概念,干看可能很难以理解,没事,往下看实例,然后再回来,我相信你一定能够理解。
学习协程是如何工作的#
协程完整的工作流程是这样的
- 定义/创建协程对象
- 将协程转为task任务
- 定义事件循环对象容器
- 将task任务扔进事件循环对象中触发
import asyncio async def hello(name):
print('Hello,', name) # 定义协程对象
coroutine = hello("World") # 定义事件循环对象容器
loop = asyncio.get_event_loop()
# task = asyncio.ensure_future(coroutine) # 将协程转为task任务
task = loop.create_task(coroutine) # 将task任务扔进事件循环对象中并触发
loop.run_until_complete(task)
输出结果,当然显而易见
Hello, World
. await与yield对比#
前面我们说,await用于挂起阻塞的异步调用接口。其作用在一定程度上类似于yield。
注意这里是,一定程度上,意思是效果上一样(都能实现暂停的效果),但是功能上却不兼容。就是你不能在生成器中使用await,也不能在async 定义的协程中使用yield。
小明不是胡说八道的。有实锤。
普通函数中 不能使用 await
再来一锤。
async 中 不能使用yield
除此之外呢,还有一点很重要的。
yield from后面可接可迭代对象,也可接future对象/协程对象;await后面必须要接future对象/协程对象
如何验证呢?
yield from 后面可接 可迭代对象,这个前两章已经说过了,这里不再赘述。
接下来,就只要验证,yield from和await都可以接future对象/协程对象就可以了。
验证之前呢,要先介绍一下这个函数:asyncio.sleep(n),这货是asyncio自带的工具函数,他可以模拟IO阻塞,他返回的是一个协程对象。
func = asyncio.sleep(2)
print(isinstance(func, Future)) # False
print(isinstance(func, Coroutine)) # True
还有,要学习如何创建Future对象,不然怎么验证。
前面概念里说过,Task是Future的子类,这么说,我们只要创建一个task对象即可。
import asyncio
from asyncio.futures import Future async def hello(name):
await asyncio.sleep(2)
print('Hello, ', name) coroutine = hello("World") # 将协程转为task对象
task = asyncio.ensure_future(coroutine) print(isinstance(task, Future)) # True
好了,接下来,开始验证。
验证通过
. 绑定回调函数#
异步IO的实现原理,就是在IO高的地方挂起,等IO结束后,再继续执行。在绝大部分时候,我们后续的代码的执行是需要依赖IO的返回值的,这就要用到回调了。
回调的实现,有两种,一种是绝大部分程序员喜欢的,利用的同步编程实现的回调。
这就要求我们要能够有办法取得协程的await的返回值。
import asyncio
import time async def _sleep(x):
time.sleep(2)
return '暂停了{}秒!'.format(x) coroutine = _sleep(2)
loop = asyncio.get_event_loop() task = asyncio.ensure_future(coroutine)
loop.run_until_complete(task) # task.result() 可以取得返回结果
print('返回结果:{}'.format(task.result()))
输出
返回结果:暂停了2秒!
还有一种是通过asyncio自带的添加回调函数功能来实现。
import time
import asyncio async def _sleep(x):
time.sleep(2)
return '暂停了{}秒!'.format(x) def callback(future):
print('这里是回调函数,获取返回结果是:', future.result()) coroutine = _sleep(2)
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(coroutine) # 添加回调函数
task.add_done_callback(callback) loop.run_until_complete(task)
输出
这里是回调函数,获取返回结果是: 暂停了2秒!
emmm,和上面的结果是一样的。nice
python 并发专题(十三):asyncio (一) 初识的更多相关文章
- python并发编程之asyncio协程(三)
协程实现了在单线程下的并发,每个协程共享线程的几乎所有的资源,除了协程自己私有的上下文栈:协程的切换属于程序级别的切换,对于操作系统来说是无感知的,因此切换速度更快.开销更小.效率更高,在有多IO操作 ...
- Python核心技术与实战——十八|Python并发编程之Asyncio
我们在上一章学习了Python并发编程的一种实现方法——多线程.今天,我们趁热打铁,看看Python并发编程的另一种实现方式——Asyncio.和前面协程的那章不太一样,这节课我们更加注重原理的理解. ...
- python 并发专题(十三):asyncio (二) 协程中的多任务
. 本文目录# 协程中的并发 协程中的嵌套 协程中的状态 gather与wait . 协程中的并发# 协程的并发,和线程一样.举个例子来说,就好像 一个人同时吃三个馒头,咬了第一个馒头一口,就得等这口 ...
- python 并发专题(十四):asyncio (三)实战
https://www.cnblogs.com/wongbingming/p/9124142.html 在实战中,将会用到以下知识点: 多线程的基本使用 Queue消息队列的使用 Redis的基本使用 ...
- python 并发专题(一):并发基础相关概念,术语等
一.线程 1.概念 线程是程序执行流的最小执行单位,是行程中的实际运作单位. 进程是一个动态的过程,是一个活动的实体.简单来说,一个应用程序的运行就可以被看做是一个进程,而线程,是运行中的实际的任务执 ...
- python 并发专题(二):python线程以及线程池相关以及实现
一 多线程实现 线程模块 - 多线程主要的内容:直接进行多线程操作,线程同步,带队列的多线程: Python3 通过两个标准库 _thread 和 threading 提供对线程的支持. _threa ...
- python 并发专题(五):离散事件仿真(事件循环生成器)
出租车队运营仿真 创建几辆出租车,每辆车会拉几个乘客,然后回家.出租车首先驶离车库,四处徘徊,寻找乘客:拉到乘客后,行程开始:乘客下车后,继续四处徘徊. 程序解释 程序的输出示例: 创建 3 辆出租车 ...
- python 并发专题(四):yield以及 yield from
一.yield python中yield的用法很像return,都是提供一个返回值,但是yield和return的最大区别在于,return一旦返回,则代码段执行结束,但是yield在返回值以后,会交 ...
- python 并发专题(三):进程以及进程池相关以及实现
一.多进程实现 multiprocess.process模块 process类 Process([group [, target [, name [, args [, kwargs]]]]]),由该类 ...
随机推荐
- JVM内存结构详解
从java编程语言说起... 1. Java编程语言简介 1.1 编程语言概述 系统级和应用级 系统级:C,C++,go,erlang 应用级:C#,Java,Python,Perl,Ruby,php ...
- (十一)Maven之profile实现多环境配置动态切换
原文链接:https://www.cnblogs.com/zeng1994/p/a442108012ffd6a97b22c63055b48fe9.html 一.多环境配置文件的放置 将不同环境下的配 ...
- PowerBuilder中调用NPOI进行Excel导出格式设置示例
// 功能 :新建excel带边框的单元格,格式为数字并显示为美元货币 // 参数 :ai_row,行号:ai_col,列号 // 返回值 :true/false // 作者 :潮崖之飔 // 日期 ...
- cb47a_c++_STL_算法_排列组合next_prev_permutation
cb47a_c++_STL_算法_排列组合next_prev_permutation 使用前必须先排序.必须是 1,2,3或者3,2,1.否者结果不准确.如果, 1,2,4,6.这样数据不会准确nex ...
- 原来你是这样的BERT,i了i了! —— 超详细BERT介绍(一)BERT主模型的结构及其组件
原来你是这样的BERT,i了i了! -- 超详细BERT介绍(一)BERT主模型的结构及其组件 BERT(Bidirectional Encoder Representations from Tran ...
- 入门大数据---Hive数据查询详解
一.数据准备 为了演示查询操作,这里需要预先创建三张表,并加载测试数据. 数据文件 emp.txt 和 dept.txt 可以从本仓库的resources 目录下载. 1.1 员工表 -- 建表语句 ...
- MongoDB快速入门教程(3.1)
3.MongoDB进阶 3.1.权限验证 以下内容适用于Mac系统用户,window系统用户请看后面文档 3.1.1.创建超级管理员用户 默认情况下连接mongodb是不需要用户名和密码的,这样不安全 ...
- Java BigDecimal和double BigDecimal类
BigDecimal类 对于不需要任何准确计算精度的数字可以直接使用float或double,但是如果需要精确计算的结果,则必须使用BigDecimal类,而且使用BigDecimal类也可以进行大数 ...
- GIT更换连接方式
1-使用 git remote -v 查看对应的克隆地址: git remote -v origin https://github.com/username/repository.git (fetch ...
- HTML重构与网页常用工具
下面这张思维导图,是我对全书大体内容的一个概括性总结: 工具 本书推荐的工具主要包含的是自动化测试,但是我觉得现行的开发环节当中实际用到的会比较少.这里就推荐一下其他方面的优秀工具: 1. YSlow ...