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

  • 一个似乎有点问题的例子
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. mac 已损坏 移至废纸篓

    1.问题描述: 从网页下载的安装包,总是提示“已损坏,移至废纸篓”这类的信息 2.原因: 系统版本过高,对安全性进行了校验. 3.解决方案:命令行输入以下命令,然后输入密码 sudo spctl -- ...

  2. [转帖]拿小本本记下的Linux Shell常用技巧(一)

    拿小本本记下的Linux Shell常用技巧(一) https://zhuanlan.zhihu.com/p/73361101 一. 特殊文件: /dev/null和/dev/tty Linux系统提 ...

  3. [转帖]从零开始入门 K8s:应用编排与管理:Job & DaemonSet

    从零开始入门 K8s:应用编排与管理:Job & DaemonSet https://www.infoq.cn/article/KceOuuS7somCYbfuykRG 陈显鹭 阅读数:193 ...

  4. javaIO -- InputStream和OutStream

    一.简介 InputStream 和 OutputStream 对于字节流的输入和输出是作为协议的存在 所以有必要了解下这两个类提供出来的基本约定,这两个类是抽象类,而且基本上没什么实现,都是依赖于子 ...

  5. LaTeX 一些用法实例(并列图片、并列表格、算法代码示例、页眉太长、下划线,等)

    横向并列两个图片 \begin{figure} \begin{minipage}{0.49\linewidth} \centering \includegraphics[width=6.5cm]{Si ...

  6. ThinkPHP读取配置信息

    use think\Config; dump(Config::get()); // 或者 dump(config());示例:dump(Config::get('database.database') ...

  7. SASS摘要

    SASS提高了代码的重复利用率,提高了效率.不用去记或者查找复杂或者繁琐的参数和书写规则. 这里简单整理了实际业务中常常用到的几个功能. 1. 父元素引用 & a { &:hover ...

  8. Jupyter修改工作目录(Anaconda环境)

    Anaconda安装时未添加环境变量 1.打开Anaconda Prompt 输入jupyter notebook --generate-config (base) C:\Users\Sroxi> ...

  9. Windows下命令行Git无法显示中文问题解决方案

    Windows下Git设置编码正常显示中文: 在 CMD 下设置环境变量 set LESSCHARSET=utf-8 在 PowerShell 下设置环境变量 $env:LESSCHARSET='ut ...

  10. recover函数捕获异常

    package main import ( //"fmt" "time" ) func test () { var m map[string]int m[&qu ...