博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python协程:从yield/send到async/await
阅读量:5988 次
发布时间:2019-06-20

本文共 3563 字,大约阅读时间需要 11 分钟。

这个文章理好了脉落。

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 asyncioimport timeimport 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 resprint("-"*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 += 1print("-"*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 += 1print("-"*10 + "test yield send " + "-"*10)N = 20sfib = 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 = 20csfib = 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.coroutinedef 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.coroutinedef 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 += 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 = 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 += 1async 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 += 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中的协程经历了很长的一段发展历程。其大概经历了如下三个阶段:

  1. 最初的生成器变形yield/send
  2. 引入@asyncio.coroutine和yield from
  3. 在最近的Python3.5版本中引入async/await关键字

转载地址:http://mtjlx.baihongyu.com/

你可能感兴趣的文章
微信服务器认证
查看>>
形态学滤波算法
查看>>
dedeCMS实现tab分页
查看>>
python3_装饰器_异常处理
查看>>
DataGridColumn中显示RadioButton
查看>>
Selenium自动化测试框架研究
查看>>
linux后台运行命令详解
查看>>
PHP代码混淆来袭,你值得拥有!
查看>>
字符串替换
查看>>
2016年U盘启动盘制作工具哪个好用?看U盘启动盘排行榜!
查看>>
Java 面向对象 之 对象数组
查看>>
Linux学习笔记6月6日任务
查看>>
Django Meta内部类
查看>>
文件查找命令使用
查看>>
给产品经理讲讲,什么是持续交付和DevOps
查看>>
龚鹏:我是怎么从程序员成为全栈GEEK的
查看>>
Linux LVM硬盘管理及LVM扩容
查看>>
2018-1-31 Linux学习笔记
查看>>
linux根目录结构分析
查看>>
python列表的增删改查
查看>>