python携程gevent_python之gevent 协程操作

因为python线程的性能问题,在python中使用多线程运行代码经常不能达到预期的效果。而有些时候我们的逻辑中又需要开更高的并发,或者简单的说,就是让我们的代码跑的更快,在同样时间内执行更多的有效逻辑、减少无用的等待。gevent就是一个现在很火、支持也很全面的python第三方协程库。

gevent是python的一个并发框架,以微线程greenlet为核心,使用了epoll事件监听机制以及诸多其他优化而变得高效。而且其中有个monkey类,将现有基于Python线程直接转化为greenlet(类似于打patch)。在运行时的具体流程大概就是:

当一个greenlet遇到IO操作时,比如访问网络/睡眠等待,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。同时也因为只有一个线程在执行,会极大的减少上下文切换的成本。

gevent基本使用

#-*- coding: utf-8 -*-

importgeventdeff1():for i in range(5):print 'run func: f1, index: %s' %i

gevent.sleep(0)deff2():for i in range(5):print 'run func: f2, index: %s' %i

gevent.sleep(0)

t1=gevent.spawn(f1)

t2=gevent.spawn(f2)

gevent.joinall([t1, t2])

运行后输出如下图所示:

由图中可以看出,f1和f2是交叉打印信息的,因为在代码执行的过程中,我们人为使用gevent.sleep(0)创建了一个阻塞,gevent在运行到这里时就会自动切换函数切换函数。也可以在执行的时候sleep更长时间,可以发现两个函数基本是同时运行然后各自等待。

在实际运用的过程中,我们如果有需要通过人为sleep来增加时间间隔或者确保部分逻辑安全的时候,此处使用就很方便了。当然,更多时候我们还是在需要进行网络请求的时候使用gevent:

#-*- coding: utf-8 -*-

from gevent importmonkey; monkey.patch_all()importgeventimportrequestsfrom datetime importdatetimedeff(url):print 'time: %s, GET: %s' %(datetime.now(), url)

resp=requests.get(url)print 'time: %s, %d bytes received from %s.' %(

datetime.now(), len(resp.text), url)

gevent.joinall([

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

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

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

])

运行上述代码,结果如下:

由上图可以看出,程序基本在同一时间触发了对三个网站的请求,然后各自进行,分别结束。也就是当gevent发现阻塞之后,让当前急需执行,然后自动切换到了另外的请求中运行。

加锁

如果需要在使用gevent的时候加锁,也是非常方便的:

#-*- coding: utf-8 -*-

importgeventfrom gevent.lock importSemaphore

sem= Semaphore(1)deff1():for i in range(5):

sem.acquire()print 'run f1, this is', i

sem.release()

gevent.sleep(1)deff2():for i in range(5):

sem.acquire()print 'run f2, that is', i

sem.release()

gevent.sleep(0.3)

t1=gevent.spawn(f1)

t2=gevent.spawn(f2)

gevent.joinall([t1, t2])

运行结果如下:

由输出可以发现,程序会同时判断是否在sleep以及是否有锁两种情况,然后执行当前的最有操作。

小结

gevent的优势不仅仅是在代码中调用方便,厉害的是它拥有的monkey机制。假设你不愿意修改原来已经写好的python代码,但是又想充分利用gevent机制,那么你就可以用monkey来做到这一点。你所要做的就是在文件开头打一个patch,那么它就会自动替换你原来的thread、socket、time、multiprocessing等代码,全部变成gevent框架。这一切都是由gevent自动完成的。注意这个patch是在所有module都import了之后再打,否则没有效果。

甚至在编写的Web App代码的时候,不需要引入gevent的包,也不需要改任何代码,仅仅在部署的时候,用一个支持gevent的WSGI服务器,就可以获得数倍的性能提升。

本文简单介绍了gevent的使用,下一篇将对gevent的部分源码进行分析。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值