Python协程:从yield/send到async/await
这个文章理好了脉落。
http://python.jobbole.com/86069/
我练 习了一番,感受好了很多。。。
Python由于众所周知的GIL的原因,导致其线程无法发挥多核的并行计算能力(当然,后来有了multiprocessing,可以实现多进程并行),显得比较鸡肋。既然在GIL之下,同一时刻只能有一个线程在运行,那么对于CPU密集的程序来说,线程之间的切换开销就成了拖累,而以I/O为瓶颈的程序正是协程所擅长的:
多任务并发(非并行),每个任务在合适的时候挂起(发起I/O)和恢复(I/O结束)
弄清楚了asyncio.coroutine和yield from之后,在Python3.5中引入的async和await就不难理解了:可以将他们理解成asyncio.coroutine/yield from的完美替身。当然,从Python设计的角度来说,async/await让协程表面上独立于生成器而存在,将细节都隐藏于asyncio模块之下,语法更清晰明了。
#!/usr/bin/env python # -*- coding: utf-8 -*- import asyncio import time import random ''' def old_fib(n): res = [0] * n index = 0 a = 0 b = 1 while index < n: res[index] = b a, b = b, a + b index += 1 return res print("-"*10 + "test old fib " + "-"*10) for fib_res in old_fib(20): print(fib_res) def fib(n): index = 0 a = 0 b = 1 while index < n: yield b a, b = b, a + b index += 1 print("-"*10 + "test yield fib " + "-"*10) for fib_res in fib(20): print(fib_res) def stupid_fib(n): index = 0 a = 0 b = 1 while index < n: sleep_cnt = yield b print("let me think {0} secs".format(sleep_cnt)) time.sleep(sleep_cnt) a, b = b, a + b index += 1 print("-"*10 + "test yield send " + "-"*10) N = 20 sfib = stupid_fib(N) fib_res = next(sfib) while True: print(fib_res) try: fib_res = sfib.send(random.uniform(0, 0.5)) except StopIteration: break def copy_fib(n): print("I am copy from fib") yield from fib(n) print("copy end") print("-"*10 + "test yield from " + "-"*10) for fib_res in copy_fib(20): print(fib_res) def copy_stupid_fib(n): print("I am copy from stupid fib") yield from stupid_fib(n) print("Copy end") print("-"*10 + "test yield from and send" + "-"*10) N = 20 csfib = copy_stupid_fib(N) fib_res = next(csfib) while True: print(fib_res) try: fib_res = csfib.send(random.uniform(0, 0.5)) except StopIteration: break @asyncio.coroutine def smart_fib(n): index = 0 a = 0 b = 1 while index < n: sleep_secs = random.uniform(0, 0.2) yield from asyncio.sleep(sleep_secs) print("Smart one think {} secs to get {}".format(sleep_secs, b)) a, b = b, a + b index += 1 @asyncio.coroutine def stupid_fib(n): index = 0 a = 0 b = 1 while index < n: sleep_secs = random.uniform(0, 0.4) yield from asyncio.sleep(sleep_secs) print("Stupid one think {} secs to get {}".format(sleep_secs, b)) a, b = b, a + b index += 1 loop = asyncio.get_event_loop() tasks = [ asyncio.async(smart_fib(10)), asyncio.async(stupid_fib(10)), ] loop.run_until_complete(async.wait(tasks)) print("All fib finished.") loop.close() ''' async def smart_fib(n): index = 0 a = 0 b = 1 while index < n: sleep_secs = random.uniform(0, 0.2) await asyncio.sleep(sleep_secs) print("Smart one think {} secs to get {}".format(sleep_secs, b)) a, b = b, a + b index += 1 async def stupid_fib(n): index = 0 a = 0 b = 1 while index < n: sleep_secs = random.uniform(0, 0.4) await asyncio.sleep(sleep_secs) print("Stupid one think {} secs to get {}".format(sleep_secs, b)) a, b = b, a + b index += 1 loop = asyncio.get_event_loop() tasks = [ asyncio.async(smart_fib(10)), asyncio.async(stupid_fib(10)), ] loop.run_until_complete(asyncio.wait(tasks)) print("All fib finished.") loop.close()
Python中的协程经历了很长的一段发展历程。其大概经历了如下三个阶段:
- 最初的生成器变形yield/send
- 引入@asyncio.coroutine和yield from
- 在最近的Python3.5版本中引入async/await关键字
Python协程:从yield/send到async/await的更多相关文章
- 理解Python协程:从yield/send到yield from再到async/await
Python中的协程大概经历了如下三个阶段:1. 最初的生成器变形yield/send2. 引入@asyncio.coroutine和yield from3. 在最近的Python3.5版本中引入as ...
- 终结python协程----从yield到actor模型的实现
把应用程序的代码分为多个代码块,正常情况代码自上而下顺序执行.如果代码块A运行过程中,能够切换执行代码块B,又能够从代码块B再切换回去继续执行代码块A,这就实现了协程 我们知道线程的调度(线程上下文切 ...
- 深入理解协程(四):async/await异步爬虫实战
本文目录: 同步方式爬取博客标题 async/await异步爬取博客标题 本片为深入理解协程系列文章的补充. 你将会在从本文中了解到:async/await如何运用的实际的爬虫中. 案例 从CSDN上 ...
- 深入理解协程(三):async/await实现异步协程
原创不易,转载请联系作者 深入理解协程分为三部分进行讲解: 协程的引入 yield from实现异步协程 async/await实现异步协程 本篇为深入理解协程系列文章的最后一篇. 从本篇你将了解到: ...
- 再议Python协程——从yield到asyncio
协程,英文名Coroutine.前面介绍Python的多线程,以及用多线程实现并发(参见这篇文章[浅析Python多线程]),今天介绍的协程也是常用的并发手段.本篇主要内容包含:协程的基本概念.协程库 ...
- Python协程笔记 - yield
生成器(yield)作为协程 yield实际上是生成器,在python 2.5中,为生成器增加了.send(value)方法.这样调用者可以使用send方法对生成器发送数据,发送的数据在生成器中会赋值 ...
- [转载] Python协程从零开始到放弃
Python协程从零开始到放弃 Web安全 作者:美丽联合安全MLSRC 2017-10-09 3,973 Author: lightless@Meili-inc Date: 2017100 ...
- python协程(yield、asyncio标准库、gevent第三方)、异步的实现
引言 同步:不同程序单元为了完成某个任务,在执行过程中需靠某种通信方式以协调一致,称这些程序单元是同步执行的. 例如购物系统中更新商品库存,需要用"行锁"作为通信信号,让不同的更新 ...
- 从yield 到yield from再到python协程
yield 关键字 def fib(): a, b = 0, 1 while 1: yield b a, b = b, a+b yield 是在:PEP 255 -- Simple Generator ...
随机推荐
- 鼠标的change事件
原本想着在<input>输入输入框中添加change事件,来实现对输入内容的限定. 当人们在使用时跟多的会直接去点击完成.所以完成按钮的点击事件会和change事件产生 冲突,所以我把验证 ...
- 一些js 插件的作用
前言: 从一些开源网站上下载下来的 后台管理系统模板一般会有很多的js ,其js 的功能是什么呢?这里随手查询了一下,记录下来 正文: 1.zDialog.js 各种弹窗插件详细案例:http://w ...
- bzoj3110
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 5881 Solved: 1958[Submit][Sta ...
- Python笔记(3)迭代器与生成器
参考自:http://www.cnblogs.com/huxi/category/251137.html 迭代器 迭代器是访问集合内元素的一种方式,他不能倒退只能一直迭代下去.可以写到for循环in后 ...
- BZOJ4540 [Hnoi2016]序列
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...
- Python终端如何输出彩色字体
实现过程: 终端的字符颜色是用转义序列控制的,是文本模式下的系统显示功能,和具体的语言无关. 转义序列是以ESC开头,即用\033来完成(ESC的ASCII码用十进制表示是27 ...
- COGS439. [网络流24题] 软件补丁
[问题描述] 对于一个软件公司来说,在发行一个新软件之后,可以说已经完成了工作.但是实际上,许多软件公司在发行一个新产品之后,还经常发送补丁程序,修改原产品中的错误(当然,有些补丁是要收费的). 如某 ...
- mate-desktop安装在其他目录时一些配置信息
1.mate-desktop安装在其他目录时一些配置信息 2.BIN目录下添加相应的mate-session_gtk2/3 3.首先配置如下环境变量 #!/bin/sh if [[ "${E ...
- 20145204&20145212信息安全系统实验三报告
实时系统的移植 实验目的与要求 1.根据实验指导书进行实时软件的安装 2.配置实验环境,并对软件进行测试. 3.正确使用连接线等仪器,注意保护试验箱. 实验内容与步骤 1.连接 arm 开发板 连接实 ...
- Java排序算法——基数排序