协程的概念协程(coroutine)通常又称之为微线程或纤程,它是相互协作的一组子程序(函数)。所谓相互协作指的是在执行函数A时,可以随时中断去执行函数B,然后又中断继续执行函数A。注意,这一过程并不是函数调用(因为没有调用语句),整个过程看似像多线程,然而协程只有一个线程执行。协程通过yield关键字和 send()操作来转移执行权,协程之间不是调用者与被调用者的关系。

协程的优势在于以下两点:执行效率极高,因为子程序(函数)切换不是线程切换,由程序自身控制,没有切换线程的开销。

不需要多线程的锁机制,因为只有一个线程,也不存在竞争资源的问题,当然也就不需要对资源加锁保护,因此执行效率高很多。

总结:协程适合处理的是I/O密集型任务,处理CPU密集型任务并不是它的长处,如果要提升CPU的利用率可以考虑“多进程+协程”的模式。

示例代码:

def consumer():

"""消费者:return:"""

count = 0

while True:

n = yield count

if not n:

return

print('Consumer%s...' % n)

count += n

def produce(c):

"""生产者:param c::return:"""

# 激活协程

c.send(None)

n = 0

while n < 5:

n = n + 1

print('Produce%s...' % n)

r = c.send(n)

print('Consumer return:%s' % r)

c.close()

if __name__ == '__main__':

c = consumer()

produce(c)

注意 : consumer函数是一个generator,把一个consumer传入produce后:首先调用c.send(None)启动生成器;

然后,一旦生产了东西,通过c.send(n)切换到consumer执行;

consumer通过yield拿到消息,处理,又通过yield把结果传回;

produce拿到consumer处理的结果,继续生产下一条消息;

produce决定不生产了,通过c.close()关闭consumer,整个过程结束。

整个流程无锁,由一个线程执行,produce和consumer协作完成任务,所以称为“协程”,而非线程的抢占式多任务。

历史回顾Python 2.2:第一次提出了生成器(最初称之为迭代器)的概念(PEP 255)。

Python 2.5:引入了将对象发送回暂停了的生成器这一特性即生成器的send()方法(PEP 342)。

Python 3.3:添加了yield from特性,允许从迭代器中返回任何值(注意生成器本身也是迭代器),这样我们就可以串联生成器并且重构出更好的生成器。

Python 3.4:引入asyncio.coroutine装饰器用来标记作为协程的函数,协程函数和asyncio及其事件循环一起使用,来实现异步I/O操作。

Python 3.5:引入了async和await,可以使用async def来定义一个协程函数,这个函数中不能包含任何形式的yield语句,但是可以使用return或await从协程中返回值。

异步I/O - 非阻塞式I/O操作。用asyncio提供的@asyncio.coroutine可以把一个generator标记为coroutine类型,然后在coroutine内部用yield from调用另一个coroutine实现异步操作。

示例代码:

import asyncio

@asyncio.coroutine

def countdown(name, num):

while num > 0:

print(f'Countdown[{name}]: {num}')

yield from asyncio.sleep(1)

num -= 1

def main():

loop = asyncio.get_event_loop()

tasks = [

countdown("A", 10), countdown("B", 5),

]

loop.run_until_complete(asyncio.wait(tasks))

loop.close()

if __name__ == '__main__':

main()为了简化并更好地标识异步IO,从Python 3.5开始引入了新的语法async和await,可以让coroutine的代码更简洁易读

请注意,async和await是针对coroutine的新语法,要使用新的语法,只需要做两步简单的替换:把@asyncio.coroutine替换为async;

把yield from替换为await。

示例代码:

import asyncio

async def countdown(name, num):

while num > 0:

print(f'Countdown[{name}]: {num}')

await asyncio.sleep(1)

num -= 1

def main():

loop = asyncio.get_event_loop()

tasks = [

countdown("A", 10), countdown("B", 5),

]

loop.run_until_complete(asyncio.wait(tasks))

loop.close()

if __name__ == '__main__':

main()

参考链接

python 协程和异步的关系_python 协程和异步I/O的实践相关推荐

  1. python 协程和异步的关系_python协程与异步协程

    在前面几个博客中我们一一对应解决了消费者消费的速度跟不上生产者,浪费我们大量的时间去等待的问题,在这里,针对业务逻辑比较耗时间的问题,我们还有除了多进程之外更优的解决方式,那就是协程和异步协程.在引入 ...

  2. python协程使用场景桌面_python协程的使用

    geventandIO 协程 微线程 遇到IO就切换 import gevent def foo(): print('hello bar') gevent.sleep(2) print('hello ...

  3. python协程和线程区别_python 协程 及其与python多线程的区别和联系

    协程(coroutine)又称微线程,纤程,是种用户级别的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时候,将寄存器上下文和栈保存到其他地方,等待切换回来的时候恢复,并从之前保存的寄存器 ...

  4. python 协程 并没有快_python协程超时

    我怎样才能使一个合作进程停止超时?在 我不明白为什么asyncio.wait()对我不起作用. 我有这样一段代码(计划实现telnet客户端):def expect(self, pattern, ti ...

  5. python类中的函数调用关系_Python中类的内置方法与继承关系实例

    1.类的内置方法 Python内部类: 所谓内部类,就是在类的内部定义的类,主要目的是为了更好的抽象现实世界. 例子: 汽车是一个类,汽车的底盘轮胎也可以抽象为类,将其定义到汽车内中,而形成内部类, ...

  6. python控制代码块逻辑关系_Python 编程中用代码缩进表示逻辑递进关系,通常用几个空格_学小易找答案...

    [判断题]在自动化现场的跟踪过程中,钢板的数据定义可以定义为一个类(class),现场的每一块钢板称为一个实例. [多选题]下列Python语句正确的是 [判断题]四联球菌.八叠球菌.葡萄球菌均是多细 ...

  7. python类与类的关系_python 类与类之间的关系

    一.依赖关系(紧密程度最低) (1)简单的定义:就是方法中传递一个对象.此时类与类之间存在依赖关系,此关系比较低. (2)实例植物大战僵尸简易版 题目要求:创建一个植物,创建一个僵尸 1.植物:名字. ...

  8. python和表格有什么关系_Python实现和Excel基础功能对应关系

    在这之前,需要先导入两个库,具体库的作用不再赘述: import pandas as pd 打开文件:Excel:双击文件打开 Python:data = pd.read_excel('XXX.xls ...

  9. python类与类的关系_python类与类的关系

    类与类之间的关系(依赖关系,大象与冰箱是依赖关系) class DaXiang: def open(self, bx): # 这里是依赖关系. 想执行这个动作. 必须传递一个bx print(&quo ...

最新文章

  1. TVM yolov3优化代码修改(编译运行OK)
  2. 计算机室活动实施方案,微机室活动计划
  3. Docker-tag
  4. idea部署tomcat项目时,在项目里打断点不能拦截
  5. SAP C4C和Gigya(Customer Data Cloud)的客户报表
  6. 图像卷积与滤波知识点整理(1)
  7. .js——alert()语句
  8. IE浏览器报错 ‘Rowspan’ 为空或不是对象
  9. python奇奇怪怪的特点
  10. SQL Server中的约束:SQL NOT NULL,UNIQUE和SQL PRIMARY KEY
  11. python怎样画立体图-Python学习(一) —— matplotlib绘制三维轨迹图
  12. [编织消息框架][JAVA核心技术]异常基础
  13. jetty 找不到html页面,记一次jetty 404问题排查修复
  14. 图解深度学习-梯度下降学习率可视化
  15. 王码86五笔使用技巧
  16. thunder链接转换普通地址下载
  17. 美国苹果股价走势图(抢先看美股三大指数新动态)
  18. vue中实现打包时代码压缩
  19. c语言tc游戏代码大全,wintcC语言小游戏画图代码.doc
  20. 超万支团队报名,历时4个月,阿里云原生编程挑战赛即将决出最后赢家

热门文章

  1. HTML5 canvas游戏工作原理
  2. 非关系型数据库--MongoDB
  3. python3里面的图片处理库 pillow
  4. 万网域名注册查询接口(API)的说明
  5. Oracle Bitmap 索引结构、如何存储及其优势
  6. spring 3.0.5+velocity tools 2.0
  7. C语言细节之四: 空指针
  8. ORA-01791: 不是 SELECTed 表达式
  9. 使用JFreeChart实现基于Web的柱状图
  10. 基于jquery的从一个页面跳转到另一个页面的指定位置的实现代码