gevent文档翻译-介绍

转载:http://www.darkbull.net/article/gevent_doc--introduction/

        翻译题记:gevent是个小巧的,性能又很nb的网络库,短短几行代码,能承受成千上万连接的服务器就出来了。simple is best,简单流水账一般地翻译下gevent官方文档作为自己的学习笔记,以便日后快速回忆,也权当帮助文档让对gevent感兴趣的朋友作为入门文 档。 ---- 装逼题记到此结束 ----

       原文地址:http://www.gevent.org/contents.html

介绍

       gevent的主要功能是作为网络库(不用再去纠结epoll, kqueue的细节),短短几行代码就能写出性能非常高效的网络服务器。它基于libevent,使用greenlet作为并行库,向目标代码提供同步的 接口(意思就是说,代码可以写的像同步阻塞socket,却可以享受远高于阻塞socket的网络io性能)

        主要特性:

  • 高效的事件循环机制(基于linux epoll,freebsd kqueue)
  • 基于greenlet的轻量级执行单元(协程、微线程,随便你怎么叫,反正就是与原生os thread不一样的但又有点类似的东东,调用开销远比os thread小,谁叫Python单进程无法享受多核的威力呢~~)
  • 重用python标准库接口完全一致(如: Event, Queue)
  • 支持socket ssl(Cooperative socket and ssl modules)
  • 可以使用gevent.monkey替换部分标准库,让阻塞socket代码无需修改就享受gevent的高效特性
  • 基于libevent-dns的DNS查询
  • 基于libevent-http的高效的WSGI服务器

安装

        linux下安装直接使用easy_install或者pip: pip install greenlet    pip install gevent

        windows下也可以使用easy_install或者pip,如果安装失败,到这里下载相应的exe

        python2.6+默认支持ssl,所以2.6之前的python版本还需要安装ssl模块(如果需要用到ssl的话)

例子

  1.   
>>> import gevent
>>> from gevent import socket >>> urls = ['www.google.com', 'www.example.com', 'www.python.org'] >>> jobs = [gevent.spawn(socket.gethostbyname, url) for url in urls] >>> gevent.joinall(jobs, timeout=2) >>> [job.value for job in jobs] ['74.125.79.106', '208.77.188.166', '82.94.164.162']

例子中创建了三个任务“并行”的执行,joinall将等待这三个任务结束后才返回,结果保存在gevent.Greenlet.value中,gevent.socket.gethostbyname用于获取域名的ip,与标准库socket.gethostbyname功能一样,只是这里的接口不会阻塞,而允许greenlet去调度。

Monkey patching

        上个例子使用gevent.socket ,如果使用标准库的socket模块,将花费大约原来三倍的时间,因为标准socket模块会阻塞python解释器直到有结果返回,当然这样就无法充分 利用cpu,所以使用gevent.socket来代替标准socket模块,应该是个不错的注意~~~~ 

        gevent提供了非常方便的接口用于在程序中替换标准模块,可以让gevent多协和环境,几条语句即可:

  1. from gevent import monkey  
  2. monkey.patch_socket()  
  3.   
  4. import urllib2 # it's usable from multiple greenlets now  

事件循环

        与其他网络库一样,gevent也有自己的事件循环机制,只是gevent的事件循环机制不需要显式的在代码中启动,因此没有类似 reactor.run() 这样的代码。gevent事件调度实现,主要与Hub对象有关,具体感兴趣的同学可以阅读gevent源码,这个Hub机制笔者也不是很明白,有空研究一 下。

        gevent默认使用系统最高效的polling机制,linux上是epoll,mac或者freebsd是kqueue,也可以设计环境变量来使用其他的机制(ms默认的就是最好的)

        gevent.core模块主要是对libevent api的封装,只是在这里只能使用异步的api

并行相关

        其实所有的greenlet协程都在一个os线程里运行与调度,因此对于io密集性的应用没有任何问题,但对于cpu密集性的应用就。。。

        在不同的greenlet协程间访问同一对象,通常情况下不需要Lock或者Semaphore,但是其他的一些与多线程有关的抽象东东还是有用的,像Event, Queue等等下:

  •         Event:
  •         AsyncResult:
  •         Queue:

轻量级线程

        spwan()方法创建一个Greenlet协程,并调用其start方法。start方法将

        如果协程在运行过程中抛出了未被处理的异常,该协程将退出运行,并将错误的信息打印出来(默认行为:错误信息被异步打印到sys.stderr):

>>> gevent.spawn(lambda : 1/0) >>> gevent.sleep(1) Traceback (most recent call last): ... ZeroDivisionError: integer division or modulo by zero <Greenlet at 0x7f2ec3a4e490: <function <lambda...>> failed with ZeroDivisionError

        Greenlet实例的一些常用方法:

  • join - 等待直到greenlet退出
  • kill - 强制结束greenlet协程
  • get - 如果协程正常结束,获取greenlet协程的运行结果;如果协程被强制结束或者在运行过程中抛出未捕获异常,重新招聘异常

        我们也可以继承Greenlet,通过重写__str__方法自定义输出。通常情况下子类在 _run方法中实现协程的逻辑,例如:

class MyNoopGreenlet(Greenlet):

    def __init__(self, seconds): Greenlet.__init__(self) self.seconds = seconds def _run(self): gevent.sleep(self.seconds) def __str__(self): return 'MyNoopGreenlet(%s)' % self.seconds

        可以异步的kill一个正在运行的greenlet协程,kill过程将“唤醒”原本sleeping的greenlet,并让其抛出一个GreenletExit异常,结束该协程

>>> g = MyNoopGreenlet(4) >>> g.start() >>> g.kill() >>> g.dead True

        kill默认抛出的GreenletExit异常,通常不会打出traceback信息,但如果向kill方法传递其他异常对象,该异常将会被重新抛出:

>>> g = MyNoopGreenlet.spawn(5) # spawn() creates a Greenlet and starts it >>> g.kill(Exception("A time to kill")) Traceback (most recent call last): ... Exception: A time to kill MyNoopGreenlet(5) failed with Exception

        kill方法有一个timeout关键字参数,用于设置超时时间(单位是秒),如果greenlet协程在指定时间内没有结束,将被强制退出

超时

        gevent许多函数都是同步的,阻塞当前协程直到操作结束,例如对协程调用kill方法,将一直阻塞直到该协程退出时。这些函数可以通过传递参数 block=False,被设置为非阻塞的。另外,许多这些同步函数支持timeout参数,设置阻塞的超时时间。(例如:Event.wait(), Greenlet.Join(), Greenlet.kill, AsyncResult.get(), ...) socket和SSLObject对象可以通过settimeout方法设置timeout。gevent还提供一个Timeout类,用于设置协程的 timeout

更多阅读

        通过Pool类控制同时运行的协程数(例子:example: dns_mass_resolve.py)

        gevent包含 TCP/SSL/HTTP/WSGI servers. See Implementing servers.

转载于:https://www.cnblogs.com/kylinfish/articles/3859926.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值