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] * nindex = 0a = 0b = 1while index < n:res[index] = ba, b = b, a + bindex += 1return resprint("-"*10 + "test old fib " + "-"*10) for fib_res in old_fib(20):print(fib_res)def fib(n):index = 0a = 0b = 1while index < n:yield ba, b = b, a + bindex += 1print("-"*10 + "test yield fib " + "-"*10) for fib_res in fib(20):print(fib_res)def stupid_fib(n):index = 0a = 0b = 1while index < n:sleep_cnt = yield bprint("let me think {0} secs".format(sleep_cnt))time.sleep(sleep_cnt)a, b = b, a + bindex += 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:breakdef 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 = 0a = 0b = 1while 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 + bindex += 1@asyncio.coroutine def stupid_fib(n):index = 0a = 0b = 1while 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 + bindex += 1loop = 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 = 0a = 0b = 1while 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 + bindex += 1async def stupid_fib(n):index = 0a = 0b = 1while 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 + bindex += 1loop = 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协程中生成器send方法的使用
关于博主 努力与运动兼备-~~有任何问题可以加我好友或者关注微信公众号,欢迎交流,我们一起进步! 微信公众号: 啃饼思录 QQ: 2810706745(i思录) 写在前面 博主最近在利用协程写异步爬虫 ...
- c++ 协程_理解Python协程(Coroutine)
由于GIL的存在,导致Python多线程性能甚至比单线程更糟. GIL: 全局解释器锁(英语:Global Interpreter Lock,缩写GIL),是计算机程序设计语言解释器用于同步线程的一种 ...
- python协程--yield和yield from
字典为动词"to yield"给出了两个释义:产出和让步.对于 Python 生成器中的 yield 来说,这两个含义都成立.yield item 这行代码会产出一个值,提供给 n ...
- 从yield 到yield from再到python协程
yield 关键字 def fib():a, b = 0, 1while 1:yield ba, b = b, a+b yield 是在:PEP 255 -- Simple Generators 这个 ...
- 理解Python的协程机制-Yield
根据PEP-0342 Coroutines via Enhanced Generators,原来仅仅用于生成器的yield关键字被扩展,成为Python协程实现的一部分.而之所以使用协程,主要是出于性 ...
- python协程系列(三)——yield from原理详解
声明:本文将详细讲解python协程的实现机理,为了彻底的弄明白它到底是怎么一回事,鉴于篇幅较长,将彻底从最简单的yield说起从最简单的生成器开始说起,因为很多看到这样一句话的时候很懵,即" ...
- python yield 协程_用yield实现python协程
刚刚介绍了pythonyield关键字,趁热打铁,现在来了解一下yield实现协程. 引用官方的说法: 与线程相比,协程更轻量.一个python线程大概占用8M内存,而一个协程只占用1KB不到内存.协 ...
- 学习笔记(35):Python网络编程并发编程-协程(yield,greenlet,gevent模块)
立即学习:https://edu.csdn.net/course/play/24458/296457?utm_source=blogtoedu 协程(yield,greenlet,gevent) 1. ...
- python 协程_Python 协程与 Go 协程的区别(一)
? "Python猫" ,一个值得加星标的公众号 花下猫语:年关将近,不知各位过得怎样?我最近有些忙,收获也挺多,以后有机会分享下.吃饭时间,追了两部剧<了不起的麦瑟尔夫人& ...
最新文章
- 轻松搞定javascript变量(闭包,预解析机制,变量在内存的分配 )
- python linux服务_Python脚本作为Linux服务/守护程序
- linux网络编程之用一张图片说明函数inet_ntop、inet_pton、inet_addr、inet_ntoa 、inet_aton函数之间的关系
- 翻手算法php,PHP各种常见经典算法总结【排序、查找、翻转等】
- 如何配置yum源,并安装FTP服务器
- jenkins安装部署全过程(linux)
- 计算机网络前三章试题,计算机网络前三章复习试题PPT课件.ppt
- 暴走漫画系列之高仿淘宝收货地址(附demo)
- vs2015下,使用人脸检测算法对FDDB数据集进行测评
- php 爬虫图片代码,python爬虫入门教程之糗百图片爬虫代码分享
- 用windows电脑制作macos系统安装U盘
- 编曲宿主DAW是什么 2023年编曲宿主软件哪个好用
- curl http或https上传下载
- SQLyog连接不上
- 精通Matlab数字图像处理与识别nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;
- 创业失败后的他们,是怎么找工作的?
- typedef的用法转
- GOF23设计模式之适配器模式
- NBA live 08 游戏解说翻译和球队战术
- linux ls -la文件信息含义
热门文章
- python编程300例_经典编程100例——python版(例75)
- 计算机考试一级考试基础知识,2016计算机一级考试msoffice基础知识
- python b站 礼物_[我叫以赏]Python获取B站UP主粉丝数
- @Configurattion注解的作用及一些列组合使用
- rstudio 修改代码间距_Windows电脑使用Rstudio会有多少错误呢
- oracle执行代码权限,利用Oracle许可执行安全模式实现更好的控制
- serum血清序列号_图文教程 将serum血清预制导入你的serum
- 【robotframework】robotframework基本使用
- HDU 6304 Chiaki Sequence Revisited
- 利用fstream进行文件拷贝测试