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 ...
随机推荐
- 精通Web Analytics 2.0 (6) 第四章:点击流分析的奇妙世界:实际的解决方案
精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第四章:点击流分析的奇妙世界:实际的解决方案 到开始实际工作的时候了.哦耶! 在本章中,您将了解到一些最重要的网络分析报告,我将 ...
- Javascript和HTML:
JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标 ...
- Codeforces Round #342 (Div. 2) C. K-special Tables(想法题)
传送门 Description People do many crazy things to stand out in a crowd. Some of them dance, some learn ...
- <<< 入侵网站类提权注入教程
---------------------------------------入侵类教程-------------------------------------------------------- ...
- MQTT开发笔记之《MQTT Server》
MQTT SERVER 性能测试报告 : http://w3yyb.sinaapp.com/archives/1601各个MQTT SERVER功能列表: http://blog.lenix.xyz/ ...
- 30个要点帮你完成java代码优化
通过java代码规范来优化程序,优化内存使用情况,防止内存泄露 可供程序利用的资源(内存.CPU时间.网络带宽等)是有限的,优化的目的就是让程序用尽可能少的资源完成预定的任务.优化通常包含两方面的内容 ...
- Android ViewPager sharedpreferences
http://www.cnblogs.com/dwinter/archive/2012/02/27/AndroidViewPager%E5%A4%9A%E9%A1%B5%E9%9D%A2%E6%BB% ...
- MSYS2的源配置
关于MSYS2的文章可以参考下面的链接,笔者不多赘述: msys2安装笔记 MSYS2 + MinGW-w64 + Git + gVim 环境配置 msys2环境搭建 msys2安装g++: pacm ...
- Android高手速成--第四部分 开发工具及测试工具
第四部分 开发工具及测试工具 主要介绍和Android开发工具和测试工具相关的开源项目. 一.开发效率工具 Json2Java根据JSon数据自动生成对应的Java实体类,还支持Parcel.Gson ...
- jQuery包装集
jQuery包装集指的是通过$()方法返回的一个元素集,这跟一般的javascript数组有所区别, 包装集在后者的基础上还有一些初始化的函数和属性. 我们可以对二者进行一个比较: jsdiv = d ...