1.gevent模块简介

gevent是一个基于libev的并发库。它为各种并发和网络相关的任务提供了整洁的API。

gevent中用到的主要模式是greenlet,它是以C扩展模块形式接入Python的轻量级协程。 greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。

2.gevent程序举例

例程一:


import geventdef foo():print('Running in foo')gevent.sleep(0)print('Explicit context switch to fooagain')def bar():print('Explicit context to bar')gevent.sleep(0)print('Implicit context switch back tobar')gevent.joinall([gevent.spawn(foo),gevent.spawn(bar),
])

例程二:

import gevent
import randomdef task(pid):"""Some non-deterministic task"""gevent.sleep(random.randint(0,2)*0.001)print('Task %s done' % pid)def synchronous():for i in range(1,10):task(i)def asynchronous():threads = [gevent.spawn(task, i) for i inxrange(10)]gevent.joinall(threads)print('Synchronous:')
synchronous()print('Asynchronous:')
asynchronous()

例程三:

import time
import gevent
from gevent importselectstart = time.time()
tic = lambda: 'at%1.1f seconds' % (time.time() - start)def gr1():# Busy waits for a second, but we don'twant to stick around...print('Started Polling: %s' % tic())select.select([], [], [], 2)print('Ended Polling: %s' % tic())def gr2():# Busy waits for a second, but we don'twant to stick around...print('Started Polling: %s' % tic())select.select([], [], [], 2)print('Ended Polling: %s' % tic())def gr3():print("Hey lets do some stuff whilethe greenlets poll, %s" % tic())gevent.sleep(1)gevent.joinall([gevent.spawn(gr1),gevent.spawn(gr2),gevent.spawn(gr3),
])

备注:

(1)程序的重要部分是将任务函数封装到gevent.spawn。初始化的greenlet列表存放在数组threads中,此数组被传给gevent.joinall 函数,gevent.joinall会阻塞当前流程,并执行所有给定的greenlet,执行流程只会在所有greenlet执行完后才会继续向下走。

(2)gevent实现了python标准库里面大部分的阻塞式系统调用,包括socket、ssl、threading和select等模块,而将这些阻塞式调用变为协作式运行(参见猴子补丁部分)。

3.猴子补丁Monkey Patch

(1)猴子补丁的由来

猴子补丁的这个叫法起源于Zope框架,大家在修正Zope的Bug的时候经常在程序后面追加更新部分,这些被称作是“杂牌军补丁(guerillapatch)”,后来guerilla就渐渐的写成了gorllia(猩猩),再后来就写了monkey(猴子),所以猴子补丁的叫法是这么莫名其妙的得来的。

后来在动态语言中,不改变源代码而对功能进行追加和变更,统称为“猴子补丁”。所以猴子补丁并不是Python中专有的。猴子补丁这种东西充分利用了动态语言的灵活性,可以对现有的语言Api进行追加,替换,修改Bug,甚至性能优化等等。

使用猴子补丁的方式,gevent能够修改标准库里面大部分的阻塞式系统调用,包括socket、ssl、threading和 select等模块,而变为协作式运行。也就是通过猴子补丁的monkey.patch_xxx()来将python标准库中模块或函数改成gevent中的响应的具有协程的协作式对象。这样在不改变原有代码的情况下,将应用的阻塞式方法,变成协程式的。

(2)猴子补丁使用时的注意事项

猴子补丁的功能很强大,但是也带来了很多的风险,尤其是像gevent这种直接进行API替换的补丁,整个Python进程所使用的模块都会被替换,可能自己的代码能hold住,但是其它第三方库,有时候问题并不好排查,即使排查出来也是很棘手,所以,就像松本建议的那样,如果要使用猴子补丁,那么只是做功能追加,尽量避免大规模的API覆盖。

虽然猴子补丁仍然是邪恶的(evil),但在这种情况下它是“有用的邪恶(useful evil)”。

(3)python中使用gevent的猴子补丁的举例

具体见下面的例子:

import socket
print(socket.socket)print("Aftermonkey patch")
from gevent importmonkey
monkey.patch_socket()
print(socket.socket)import select
print(select.select)
monkey.patch_select()
print("Aftermonkey patch")
print(select.select)

程序输出如下:

class 'socket.socket'
After monkey patch
class 'gevent.socket.socket'built-in function select
After monkey patch
function select at 0x1924de8

学习资料参考于:

http://xlambda.com/gevent-tutorial/

python并发编程gevent模块以及猴子补丁学习相关推荐

  1. Python并发编程理论篇

    Python并发编程理论篇 前言 很多人学习python,不知道从何学起. 很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手. 很多已经做案例的人,却不知道如何去学习更加高深的知识 ...

  2. 《转载》Python并发编程之线程池/进程池--concurrent.futures模块

    本文转载自 Python并发编程之线程池/进程池--concurrent.futures模块 一.关于concurrent.futures模块 Python标准库为我们提供了threading和mul ...

  3. 深入浅出讲解Python并发编程

    微信公众号:运维开发故事,作者:素心 Python并发编程 本文比较长,绕的也比较快,需要慢慢跟着敲代码并亲自运行一遍,并发编程本身来说就是编程里面最为抽象的概念,单纯的理论确实很枯燥,但这是基础,基 ...

  4. 你知道什么是Python里的鸭子类型和猴子补丁吗?

    作者 |  梁云1991 来源 | Python与算法之美(ID:Python_Ai_Road) 有时候我们会听到Python里所谓的鸭子类型和猴子补丁的说法,乍一听还以为是来到了动物园,Python ...

  5. python并发编程之协程

    python并发编程之协程 1.协程: 单线程实现并发 在应用程序里控制多个任务的切换+保存状态 优点: 应用程序级别速度要远远高于操作系统的切换 缺点: 多个任务一旦有一个阻塞没有切,整个线程都阻塞 ...

  6. python并发编程调优_Python并发编程-并发解决方案概述

    Python并发编程-并发解决方案概述 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.并发和并行区别 1>.并行(parallel) 同时做某些事,可以互不干扰的同一个时 ...

  7. python 并发编程 多进程 目录

    python multiprocessing模块 介绍 python 开启进程两种方法 python 并发编程 查看进程的id pid与父进程id ppid python 并发编程 多进程 Proce ...

  8. Python并发编程系列之多进程(multiprocessing)

    1 引言 本篇博文主要对Python中并发编程中的多进程相关内容展开详细介绍,Python进程主要在multiprocessing模块中,本博文以multiprocessing种Process类为中心 ...

  9. Python并发编程之线程池/进程池

    引言 Python标准库为我们提供了threading和multiprocessing模块编写相应的多线程/多进程代码,但是当项目达到一定的规模,频繁创建/销毁进程或者线程是非常消耗资源的,这个时候我 ...

  10. Python并发编程之进程间通信

    Python并发编程之进程间通信 一.Python进程间通信 二.使用队列Queue进行进程间通信 2.1 Queue实例中的方法和属性 2.2 使用Queue进行进程间通信的代码示例 三.使用管道P ...

最新文章

  1. CentOS6.10在VMware(虚拟机)安装过程
  2. iview weapp icon组件自定义图标 小程序
  3. 分布式与人工智能课程(part16)--深度学习
  4. java面向对象程序设计(jdk1.6)第三版 目录页数_Java面向对象程序设计/普通高等教育计算机规划教材简介,目录书摘...
  5. 在linux下 用户的密码错误,linux – 常规用户帐户之间的su失败,“su:密码错误”...
  6. 小米要用 AI + IoT 做年轻人的第一套智能家居
  7. 创建sprite 组
  8. 类k-均值算法无法解决非簇状分布的数据聚类问题_无监督机器学习中,有哪些最常见的聚类算法?...
  9. 西门子g120变频器接线图_西门子S7—1500第二十一讲(G120变频器第一篇)
  10. oracle 将钱转换万元单位,oracle中单位换算。
  11. jQuery中的Sizzle引擎分析
  12. 搭建简单windows版NAS
  13. Android 开发都有哪些好书值得一读?
  14. 10.2.2.7 -DHCP 和 DNS 服务
  15. 开源运维自动化平台-opendevops
  16. HDU/HDOJ 4043 BUPT 235 FXTZ II 2011ACM北京网络赛 D题
  17. 从零学本体dApp开发(20): 分片合约也有Runtime dAPI
  18. 微软解释“云下载”如何重新安装Windows 10
  19. 爬取绝对领域jk制服区全图片 新人笔记
  20. C语言malloc初始化问题

热门文章

  1. 修改oracle用户资源限制,oracle用户登陆失败次数限制修改
  2. esxi 创建虚拟交换机_对vSphere虚拟交换机的理解
  3. Composition
  4. 【Java代码之美】 -- Java11新特性解读
  5. ffmpeg 视频音频合成新视频
  6. 微信小程序强制更新版本
  7. 十二月英语——加入了新元素
  8. python绘制网络拓扑图_python 画网络拓扑图
  9. win10怎么将计算机放桌面壁纸,windows10自带壁纸在哪里_win10电脑自带的桌面壁纸保存在哪...
  10. 登录网易云显示服务器地址,[网易云音乐]登录流程还原