简介

没有切换开销。因为子程序切换不是线程切换,而是由程序自身控制,没有线程切换的开销,因此执行效率高,

不需要锁机制。因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多

Python对协程的支持还非常有限,用在generator中的yield可以一定程度上实现协程。

yield

传统的生产者-消费者模型是一个线程写消息,一个线程取消息,通过锁机制控制队列和等待,但一不小心就可能死锁。

如果改用协程,生产者生产消息后,直接通过yield跳转到消费者开始执行,待消费者执行完毕后,切换回生产者继续生产,效率极高

代码

import time

def consumer():

r = ''

while True:

n = yield r

if not n:

return

print('[CONSUMER] Consuming %s....' % n)

r = '200 OK'

def produce(c):

c.next()

n = 0

while n < 5:

n = n + 1

print('[PRODUCER] Producing %s...' % n)

r = c.send(n)

print('[PRODUCER] Consumer return: %s\n' % r)

c.close()

if __name__=='__main__':

c = consumer()

produce(c)

结果

[PRODUCER] Producing 1...

[CONSUMER] Consuming 1....

[PRODUCER] Consumer return: 200 OK

[PRODUCER] Producing 2...

[CONSUMER] Consuming 2....

[PRODUCER] Consumer return: 200 OK

[PRODUCER] Producing 3...

[CONSUMER] Consuming 3....

[PRODUCER] Consumer return: 200 OK

[PRODUCER] Producing 4...

[CONSUMER] Consuming 4....

[PRODUCER] Consumer return: 200 OK

[PRODUCER] Producing 5...

[CONSUMER] Consuming 5....

[PRODUCER] Consumer return: 200 OK

分析

首先调用c.next()启动生成器

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

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

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

整个过程无锁,由一个线程执行,producer和consumer写作完成任务,所以叫做协程

gevent

Python通过yield提供了对协程的基本支持,但是不完全。而第三方的gevent为Python提供了比较完善的协程支持

gevent是第三方库,通过greenlet实现协程,其基本思想是:

当一个greenlet遇到IO操作时(比如访问网络),就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。

import gevent

def f(n):

for i in range(n):

print gevent.getcurrent(), i

g1 = gevent.spawn(f, 5)

g2 = gevent.spawn(f, 5)

g3 = gevent.spawn(f, 5)

g1.join()

g2.join()

g3.join()

结果

0

1

2

3

4

0

1

2

3

4

0

1

2

3

4

可以看出3个greenlet依次运行,而不是交替运行

要让greenlet交替运行,可以通过gevent.sleep()交出控制权

import gevent

def f(n):

for i in range(n):

print gevent.getcurrent(), i

gevent.sleep(1)

g1 = gevent.spawn(f, 3)

g2 = gevent.spawn(f, 3)

g3 = gevent.spawn(f, 3)

g1.join()

g2.join()

g3.join()

结果

0

0

0

1

1

1

2

2

2

可以看出3个greenlet是交替执行

如果把循环改为1000,让执行次数执行时间长些,查看进程,可以看到线程只有一个。

当然,实际代码中,不可能用gevent.sleep()去切换协程,而是在执行IO操作是,gevent自动切换,参考代码如下

import gevent

from gevent import monkey; monkey.patch_all()

import urllib2

def f(url):

print 'GET: %s' % url

resp = urllib2.urlopen(url)

data = resp.read()

print '[%d] bytes received from %s\n' %(len(data), url)

gevent.joinall([

gevent.spawn(f, 'http://www.cnblogs.com/kaituorensheng/'),

gevent.spawn(f, 'https://www.python.org/'),

gevent.spawn(f, 'https://www.baidu.com'),

])

执行结果

GET: http://www.cnblogs.com/kaituorensheng/

GET: https://www.python.org/

GET: https://www.baidu.com

[227] bytes received from https://www.baidu.com

[14667] bytes received from http://www.cnblogs.com/kaituorensheng/

[47348] bytes received from https://www.python.org/

可以看到3个url结束顺序并不是依次执行完的。

使用gevent,可以获得极高的并发性能,但gevent只能在Unix/Linux下运行,在Windows下不保证正常安装和运行。

由于gevent是基于IO切换的协程,所以最神奇的是,我们编写的Web App代码,不需要引入gevent的包,也不需要改任何代码,仅仅在部署的时候,用一个支持gevent的WSGI服务器,立刻就获得了数倍的性能提升。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

python携程使用_简单了解python gevent 协程使用及作用相关推荐

  1. python中输入字符串_简单讲解Python中的字符串与字符串的输入输出

    简单讲解Python中的字符串与字符串的输入输出 发布于 2016-03-26 14:35:42 | 110 次阅读 | 评论: 0 | 来源: 网友投递 Python编程语言Python 是一种面向 ...

  2. go 怎么等待所有的协程完成_优雅地等待子协程执行完毕

    goroutine模拟了线程级别的返场的能力,但它的执行需要主协程给机会.一般的作法用sleep,chan阻塞,看起来让人不爽,本文介绍sync.WaitGroup 类型结合 defer 的特性,给出 ...

  3. python中len用法_简单介绍Python中的len()函数的使用

    简单介绍Python中的len()函数的使用 函数:len() 1:作用:返回字符串.列表.字典.元组等长度 2:语法:len(str) 3:参数:str:要计算的字符串.列表.字典.元组等 4:返回 ...

  4. python进程线程协程区别_进程和线程、协程的区别

    现在多进程多线程已经是老生常谈了,协程也在最近几年流行起来.python中有协程库gevent,py web框架tornado中也用了gevent封装好的协程.本文主要介绍进程.线程和协程三者之间的区 ...

  5. python画圆花_简单实现python画圆功能

    本文实例为大家分享了python实现画圆功能的具体代码,供大家参考,具体内容如下 import numpy as np import matplotlib.pyplot as plt from mat ...

  6. 协程 进程_进程,线程,协程的关系

    对于很多WEB服务器的开发人员,编程前几年大多以实现业务代码为主,很少接触或者系统的学习服务器的进程,线程,协成的概念和应用,下面我就进程,线程,协成在Nginx服务器中的应用对比浅析: 关系图: 概 ...

  7. python打开excel窗口_简单介绍python在CMD界面读取excel所有数据

    这篇文章主要介绍了python在CMD界面读取excel所有数据,帮助大家更好的利用python办公,感兴趣的朋友可以了解下 代码 import xlrd import os from prettyt ...

  8. python变量作用域图解_简单了解Python变量作用域正确使用方法

    在写代码的时候,免不了要使用变量.但程序中的一个变量并不一定是在哪里都可以被使用,根据情况不同,会有不同的"有效范围". 看这样一段代码: def func(x): print ( ...

  9. python 表格格式输出_简单介绍python输出列表元素的所有排列形式

    今天小编就为大家分享一篇浅谈python输出列表元素的所有排列形式,具有很好的参考价值,希望对大家有所帮助.一起跟随小编过来看看吧 例如: ['a', 'b', 'c'] 输出 ['a', 'b', ...

最新文章

  1. P1502 窗口的星星 离散化+扫描线
  2. 利用ViewPager+Fragment+actionbar实现可左右滑动的Action Tab
  3. 【Google给毕业生的忠告】
  4. Linux内核如何管理内存
  5. python直方图的拟合_从一组数据python中将两个高斯拟合成直方图
  6. ubuntu anaconda配置环境变量_Anaconda从下载到环境变量配置(windows)
  7. 【小程序】展示弹窗常见API详解
  8. Java复制文件的4种方式
  9. linux软路由 iptv,LEDE x64软路由实现任意网口观看上海电信4K IPTV或上网
  10. 微软亚洲研究院公布12项顶级研发成果(组图)
  11. c语言常量要const,C语言常量-C语言const-嗨客网
  12. 关于word中如何生成自动目录以及页码编排
  13. 无能的力量 -- 《看见》
  14. 计算机处理器i3 i5,realme Book笔记本高清渲染图曝光 配置上搭载11代酷睿i3/i5处理器...
  15. 北京办理互联网经营许可证(ICP证)的要求
  16. Centos安装JDK,RPM安装JDK
  17. Python快速入门(上)
  18. nagios 安装部署试验
  19. 渗透测试学习笔记20.11.20
  20. 白板体现计算机什么方面应用,白板汉字论文,关于电子白板在小学低年级识字写字教学中的运用相关参考文献资料-免费论文范文...

热门文章

  1. BUFF 在C++ 中取其中一部分 并且写到固定的目录下
  2. 【JAVA基础】HashSet、LinkedHashSet、TreeSet使用区别
  3. MFC中 AfxBeginThread()的函数
  4. ON_COMMAND和ON_MESSAGE的区别
  5. linux目录表及功能n鸟哥,鸟哥linux学习之-文件属性跟系统目录
  6. oracle中多个数据库连接池,数据库连接池为什么要建立多个连接
  7. 随想录(嵌入式工程师的出路)
  8. 随想录(从开源的宝库中学习)
  9. oracle时分秒修改值_Oracle SQL Developer显示的时间包含时分秒的设置方法
  10. 自家主机建云服务器_如何创建一台Linux云主机?