python并发编程gevent模块以及猴子补丁学习
来源:互联网 发布:linux查看javahome 编辑:程序博客网 时间:2024/06/06 01:57
1.gevent模块简介
gevent是一个基于libev的并发库。它为各种并发和网络相关的任务提供了整洁的API。
gevent中用到的主要模式是greenlet,它是以C扩展模块形式接入Python的轻量级协程。 greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。
2.gevent程序举例
例程一:
import gevent def 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 geventimport random def 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 timeimport geventfrom gevent importselect start = 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 socketprint(socket.socket) print("Aftermonkey patch")from gevent importmonkeymonkey.patch_socket()print(socket.socket) import selectprint(select.select)monkey.patch_select()print("Aftermonkey patch")print(select.select)程序输出如下:
class 'socket.socket'After monkey patchclass 'gevent.socket.socket'built-in function selectAfter monkey patchfunction select at 0x1924de8
学习资料参考于:
http://xlambda.com/gevent-tutorial/
- python并发编程gevent模块以及猴子补丁学习
- Python 猴子补丁
- Python gevent模块
- python并发编程greenlet模块学习
- python 并发编程(多进程、多线程、gevent)
- [Python网络编程]gevent httpclient以及网页编码
- [python]gevent学习(1)
- Python服务端编程Gevent框架学习路线推荐
- [python]gevent学习(3)-snmp
- ubuntu12.04.4下安装python模块gevent
- python中的协程模块gevent
- 【七月Python入门】 第七课并发编程以及系统常用模块
- 猴子补丁
- 猴子补丁
- gevent模块
- Python服务端编程Gevent框架视频教程
- python Gevent – 高性能的Python并发框架
- python Gevent – 高性能的Python并发框架
- PAT-B 1052. 卖个萌
- 如何做自己不想做的事情,却必须要去做的事情
- 泛型编程 模板1
- ios学习路线—iOS高级(GCD)
- RHEL7: How to get started with Systemd.
- python并发编程gevent模块以及猴子补丁学习
- OpenCV Mat数据类型指针ptr的使用
- 误人子弟之横向ListView(HorizontalListView)简单解析
- Python多进程并发操作中进程池Pool的应用
- Blender 工具使用—–准星
- 踩坑[INSTALL_FAILED_PERMISSION_LEVEL_DOWNGRADE]
- Hadoop 词频权重公式
- python的debug调试工具pdb学习
- Android studio 2.0 的安装的全程截图,手把手教学,亲自实践。