• gevent协程


    Python通过yield提供了对协程的基本支持,但是不完全。而第三方的gevent为Python提供了比较完善的协程支持。

    gevent是第三方库,通过greenlet实现协程,其基本思想是:

    当一个greenlet遇到IO操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。

    由于切换是在IO操作时自动完成,所以gevent需要修改Python自带的一些标准库,这一过程在启动时通过monkey patch完成:

    先了解greenlet,这个库用来学习的 功能不是很多。

     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3  
     4  
     5 from greenlet import greenlet
     6  
     7  
     8 def test1():
     9     print 12
    10     #切换到g2
    11     gr2.switch()
    12     print 34
    13     #切换到g2继续执行上次的任务
    14     gr2.switch()
    15  
    16  
    17 def test2():
    18     print 56
    19     gr1.switch()
    20     print 78
    21  
    22 gr1 = greenlet(test1)
    23 gr2 = greenlet(test2)
    24 gr1.switch()
    View Code

    结果:

    12
    56
    34
    78

    通过switc方法可以控制 协程什么时候切换,协程会记录上次执行的点然后导入这个点继续执行

    gevent库方法(基于greenlet来做的):

     1 from gevent import monkey; monkey.patch_all()
     2 import gevent
     3 import urllib2
     4 
     5 def f(url):
     6     print('GET: %s' % url)
     7     resp = urllib2.urlopen(url)
     8     data = resp.read()
     9     print('%d bytes received from %s.' % (len(data), url))
    10 
    11 #这里就不想greenlet需要手动切换,这里是自动切换
    12 gevent.joinall([
    13         gevent.spawn(f, 'https://www.python.org/'),
    14         gevent.spawn(f, 'https://www.yahoo.com/'),
    15         gevent.spawn(f, 'https://github.com/'),
    16 ])
    View Code

    openstack中用到的协程模块eventlet

     1 import eventlet
     2 from eventlet.green import urllib2
     3 
     4 
     5 urls = [
     6     "http://www.baidu.com",
     7     "https://github.com/",
     8     "http://www.qq.com",
     9 ]
    10 
    11 
    12 def fetch(url):
    13     print(url)
    14     return url,urllib2.urlopen(url).read()
    15 
    16 
    17 pool = eventlet.GreenPool()
    18 
    19 
    20 for url,body in pool.imap(fetch, urls):
    21     print("go:%s === body-len:%d"%(url,len(body)))
    View Code
  • 相关阅读:
    java注解-笔记
    java重载与重写-笔记
    java中(equals与==)- 笔记
    Java迭代与递归-笔记
    C++指针悬挂-笔记
    极速倒入sql记录到excel表格,19个子段5万条记录只需30秒
    利用MCI的方法可以方便的实现光驱门的开关
    如何让你的程序在任务列表隐藏
    如何实现遍历文件夹中的所有文件
    识别操作系统版本
  • 原文地址:https://www.cnblogs.com/menkeyi/p/7145464.html
Copyright © 2020-2023  润新知