协程工作的特点是遇到阻塞或耗时的任务时就切换,协程的生存依赖于线程,线程依赖于进程

  • 一个似乎有点问题的例子
import gevent,time

def kisscpc(num):
for i in range(num):
print ("吻了第%s下陈培昌"%(i+),gevent.getcurrent())
time.sleep() def kisscj(num):
for i in range(num):
print ("吻了第%s下程劲"%(i+),gevent.getcurrent())
time.sleep() def kissxxd(num):
for i in range(num):
print ("吻了第%s下徐晓冬"%(i+),gevent.getcurrent())
time.sleep() g1 = gevent.spawn(kisscj,)
g2 = gevent.spawn(kisscpc,)
g3 = gevent.spawn(kissxxd,)
g1.join()
g2.join()
g3.join()

输出结果:

吻了第1下程劲 <Greenlet at 0x7fe77eed7648: kisscj()>
吻了第2下程劲 <Greenlet at 0x7fe77eed7648: kisscj()>
吻了第3下程劲 <Greenlet at 0x7fe77eed7648: kisscj()>
吻了第1下陈培昌 <Greenlet at 0x7fe77eed7a48: kisscpc()>
吻了第2下陈培昌 <Greenlet at 0x7fe77eed7a48: kisscpc()>
吻了第1下徐晓冬 <Greenlet at 0x7fe77eed7b48: kissxxd()>
吻了第2下徐晓冬 <Greenlet at 0x7fe77eed7b48: kissxxd()>
吻了第3下徐晓冬 <Greenlet at 0x7fe77eed7b48: kissxxd()>
吻了第4下徐晓冬 <Greenlet at 0x7fe77eed7b48: kissxxd()>
吻了第5下徐晓冬 <Greenlet at 0x7fe77eed7b48: kissxxd()>

貌似这样的结果并未能达到我们所期待的并发效果,任务仍旧是按部就班的执行。答案在于使用gevent时,相关的一切都要更换成gevent的

  • 耗时,阻塞部分换成gevent库的实现
import gevent,time

def kisscpc(num):
for i in range(num):
print ("吻了第%s下陈培昌"%(i+),gevent.getcurrent())
#time.sleep()
gevent.sleep()
def kisscj(num):
for i in range(num):
print ("吻了第%s下程劲"%(i+),gevent.getcurrent())
#time.sleep()
gevent.sleep()
def kissxxd(num):
for i in range(num):
print ("吻了第%s下徐晓冬"%(i+),gevent.getcurrent())
   #time.sleep()
gevent.sleep()
g1 = gevent.spawn(kisscj,)
g2 = gevent.spawn(kisscpc,)
g3 = gevent.spawn(kissxxd,)
g1.join()
g2.join()
g3.join()

输出结果:

吻了第1下程劲 <Greenlet at 0x7f2af804e648: kisscj()>
吻了第1下陈培昌 <Greenlet at 0x7f2af804ea48: kisscpc()>
吻了第1下徐晓冬 <Greenlet at 0x7f2af804eb48: kissxxd()>
吻了第2下程劲 <Greenlet at 0x7f2af804e648: kisscj()>
吻了第2下陈培昌 <Greenlet at 0x7f2af804ea48: kisscpc()>
吻了第2下徐晓冬 <Greenlet at 0x7f2af804eb48: kissxxd()>
吻了第3下程劲 <Greenlet at 0x7f2af804e648: kisscj()>
吻了第3下徐晓冬 <Greenlet at 0x7f2af804eb48: kissxxd()>
吻了第4下徐晓冬 <Greenlet at 0x7f2af804eb48: kissxxd()>
吻了第5下徐晓冬 <Greenlet at 0x7f2af804eb48: kissxxd()>

哟比~这才是我们期盼的!

但是,对于一些早期的代码,每个任务的耗时部分仍有可能采用了常规的代码写法(而不是gevent.方法名),这就意味着,我们需要改动代码的绝大多数部分

这时,猴子补丁就派上用场了

import gevent,time
from gevent import monkey
monkey.patch_all()
def kisscpc(num):
for i in range(num):
print ("吻了第%s下陈培昌"%(i+),gevent.getcurrent())
time.sleep()
#gevent.sleep()
def kisscj(num):
for i in range(num):
print ("吻了第%s下程劲"%(i+),gevent.getcurrent())
time.sleep()
#gevent.sleep()
def kissxxd(num):
for i in range(num):
print ("吻了第%s下徐晓冬"%(i+),gevent.getcurrent())
time.sleep()
#gevent.sleep()
g1 = gevent.spawn(kisscj,)
g2 = gevent.spawn(kisscpc,)
g3 = gevent.spawn(kissxxd,)
g1.join()
g2.join()
g3.join()

输出结果:

吻了第1下程劲 <Greenlet at 0x7f97e4981948: kisscj()>
吻了第1下陈培昌 <Greenlet at 0x7f97e4981a48: kisscpc()>
吻了第1下徐晓冬 <Greenlet at 0x7f97e4981b48: kissxxd()>
吻了第2下程劲 <Greenlet at 0x7f97e4981948: kisscj()>
吻了第2下陈培昌 <Greenlet at 0x7f97e4981a48: kisscpc()>
吻了第2下徐晓冬 <Greenlet at 0x7f97e4981b48: kissxxd()>
吻了第3下程劲 <Greenlet at 0x7f97e4981948: kisscj()>
吻了第3下徐晓冬 <Greenlet at 0x7f97e4981b48: kissxxd()>
吻了第4下徐晓冬 <Greenlet at 0x7f97e4981b48: kissxxd()>
吻了第5下徐晓冬 <Greenlet at 0x7f97e4981b48: kissxxd()>

我们看到仅仅用了monkey.patch_all()就达到了期待的效果,而其他方面几乎没什么改变

python协程初步--gevent库使用以及解释什么是猴子补丁monkey_patch的更多相关文章

  1. Python 协程(gevent)

    协程,又叫微线程,协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈.因此: 协程能保留上 ...

  2. python 协程 greenlet gevent

    一.并发的本质 切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制),一种情况是该任务发生了阻塞,另外一种情况是该任务计算的时间过长时间片到了 二.协程 ...

  3. python协程初步---一个生成器的实现

    和列表那种一下占据长度为n的内存空间不同的是,生成器在调用的过程中逐步占据内存空间,因此有着很大的优势 一个斐波纳契数列的例子 def myfibbo(num): a,b=, count= while ...

  4. python协程初步---一个迭代器的实现

    一般认为迭代器就是实现了两个方法__iter__和__next__ 先创建这样一个类 from collections import Iterable from collections import ...

  5. 【python】-- 协程介绍及基本示例、协程遇到IO操作自动切换、协程(gevent)并发爬网页

    协程介绍及基本示例 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是协程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他 ...

  6. 并发编程(六)——进程/线程池、协程、gevent第三方库

    进程/线程池.协程.gevent第三方库 一.进程/线程池 1.进程池 (1)什么是进程池 如果需要创建的子进程数量不大,可以直接利用multiprocess中的Process来创建.但是当需要创建上 ...

  7. python协程详解,gevent asyncio

    python协程详解,gevent asyncio 新建模板小书匠 #协程的概念 #模块操作协程 # gevent 扩展模块 # asyncio 内置模块 # 基础的语法 1.生成器实现切换 [1] ...

  8. 5分钟完全掌握Python协程

    本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 1. 协程相关的概念 1.1 进程和线程 进程(Process)是应用程序启动的实例,拥有代码.数据 ...

  9. 初学Python——协程

    进程.线程和协程区分 我们通常所说的协程Coroutine其实是corporate routine的缩写,直接翻译为协同的例程,一般我们都简称为协程. 在linux系统中,线程就是轻量级的进程,而我们 ...

随机推荐

  1. 第一周----常量和final

    符号常量   final 字面常量:1 2 int  a=3;   a是变量   3是常量        

  2. Java 应用程序的运行机制

    计算机高级语言: 编译型 (C)                             解释性(JS)Java 使两种类型的结合 java     编译器    class   \|/jvm     ...

  3. 【牛客网】Finding Hotel

    [牛客网]Finding Hotel 忘记K远点对的剪枝的我有点自闭 事实上我们只要先建一棵KD树出来,维护一下所在的矩形,和子树里的最小值 每次查询的时候如果最小值比查询的值要大的话就退出 当前的答 ...

  4. java源码 -- AbstractMap

    AbstractMap抽象类实现了一些简单且通用的方法,本身并不难.但在这个抽象类中有两个方法非常值得关注,keySet和values方法源码的实现可以值的学习. 抽象类通常作为一种骨架实现,为各自子 ...

  5. Python之并行编程笔记

    概述: 非并发: 1 程序由单个步骤序列构成  2 包含独立子任务的程序执行性能低 并发:  1 异步.高效  2 分解子任务.简化流程与逻辑 进程process:1 一个程序的执行实例  2 每个进 ...

  6. linux上启动tomcat报错:Failed to read schema document 'http://www.springframework.org/schema/data/mongo/spring-mongo-2.0.xsd

    本文原文连接: http://blog.csdn.net/bluishglc/article/details/7596118 ,转载请注明出处! spring在加载xsd文件时总是先试图在本地查找xs ...

  7. (十)mybatis之缓存

    一.缓存的意义 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)去查询,从缓存中进行查询,从而提高查询效率,解决了高并发系统的性能问题. 二.mybatis ...

  8. svn之合并分支

    学习连接 svn的merge使用例子

  9. 奇妙的算法【9】YC每个小孩的糖果数,找公约数,最少硬币数

    1,每个小孩的糖果数量是多少 有p个小孩,c个糖果,刚开始第1个小孩发一个糖果,第2个小孩发两个糖果,第p个小孩发p个糖果,如果糖果没有发完,就接着[注意]第1个小孩发p+1个糖果.....第p个小孩 ...

  10. JS使用MD5加密

    MD5加密JS代码 /* * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message * Digest Algor ...