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 ...
随机推荐
- java类的初始化块/执行顺序,实例化对象数据赋值
java里初始化一个类的对象,通过初始化快或者构造方法进行数据赋值.与其相关的执行代码有这么几种: 静态初始化块 初始化块 构造方法 静态初始化块 静态初始化块只在类加载时执行一次,同时静态初始化块只 ...
- delphi 取cpu号
从网上找的取cpu号 在d7中测试通过了 push,move,pop ...有点难 现在的水平我也就只能拿来主义了 /// <summary>/// 取cpu号/// </summa ...
- 教你一招:win 7 或win 10右键菜单 添加获取管理员权限
当我们从经典的 windows XP 系统升级到 win 7 或 win 10,我们会发现,想要删除一些文件时,总是提示被占用或者是没有权限,很是烦恼. 这里,写下解决这个烦恼的办法,以安慰心里的不平 ...
- python3中用HTMLTestRunner.py报ImportError: No module named 'StringIO'如何解决
python3中用HTMLTestRunner.py报ImportError: No module named 'StringIO'的解决方法: 1.原因是官网的是python2语法写的,看官手动把官 ...
- Werewolf流程分析
werewolf大致流程 首先是房主创建房间,创建成功以后房主开启web socket连接. 其他成员加入房间,加入房间后新成员和老成员的游戏玩家列表都会更新,然后新成员也要开启web socket连 ...
- Java 集合类详解
集合类说明及区别 Collection ├List │├LinkedList │├ArrayList │└Vector │ └Stack └Set Map ├Hashtable ├HashMap └W ...
- 通过grep来进行日志分析,grep -C和配合awk实际对catalina.out使用案例
本文介绍通过grep来进行日志分析,主要介绍grep -C和配合awk实际对catalina.out使用案例 grep可以对日志文件进行筛选,统计,查询,快速定位bug. 首先,你的日志需要比较规范, ...
- JS操作cookies方法
/** * 写入cookies */function setCookie(name, value) { var time = "1d"; //默认一天失效 var strsec = ...
- ArcGIS Server开发教程系列(7)使用ArcGIS API for Javascript-Hello World
ArcGIS API for Javascript API下载地址:http://support.esrichina-bj.cn/2011/0223/960.html 选择最新的下载就好了,目前是3 ...
- Spring 入门知识
------------------------------------------------------------------------------------- Spring是什么? Spr ...