python--协程

import gevent
#自动IO切换
def foo():
    print("running in foo")
    gevent.sleep(2)
    print('Explicit context switch to foo again')

def bar():
    print('Explict context to bar')
    gevent.sleep(2)
    print('Implicit context switch back to bar')

def run3():
    print("running func3")
    gevent.sleep(0)
    print("running func3 again")

gevent.joinall([
    gevent.spawn(foo),
    gevent.spawn(bar),
    gevent.spawn(run3)
])

 

实现一个异步IO并发的小爬虫:

from urllib import request
import gevent
from gevent import  monkey

monkey.patch_all()
#urllib的IO阻塞gevent检测不到,所以即使异步程序执行起来也是串行
# 所以需要使用monkey.patch_all(),作用是把当前程序所有的IO操作做上标记,使程序能够异步切换
def f(url):
    print('GET:%s' % url)
    resp = request.urlopen(url)
    data = resp.read()
    f = open('/home/guqing/url.html','wb')
    f.write(data)
    f.close()
    print("%d bytes received from %s."%(len(data),url))

gevent.joinall([
    gevent.spawn(f,'https://wwww.baidu.com'),
    gevent.spawn(f,'https://www.yahoo.com/'),
    gevent.spawn(f,'https:github.com/'),
])

 

使用yield实现简单协程:

import time
def consumer(name):
    print("-------------->starting eating baozi....")
    while True:
        new_baozi = yield
        print("[%s] is eating baozi %s"%(name,new_baozi))
        #time.sleep(1)


def producer():
    r1 = con.__next__()
    r2 = con2.__next__()
    n = 0
    while n < 5:
        n += 1
        con.send(n)
        con2.send(n)
        time.sleep(2)
        print("\033[32;1m[producer]\033[0m is making baozi %s"%n)



if __name__ == '__main__':
    con = consumer("c1")
    con2 = consumer("c2")
    p = producer()

 

greenlet手动切换协程:

__author__="Tim"
from greenlet import greenlet

def test1():
    print(12)
    gr2.switch()
    print(34)
    gr2.switch()

def test2():
    print(56)
    gr1.switch()
    print(78)
    gr1.switch()

gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()

 

gevent自动切换协程:

 

posted @ 2017-02-28 21:49  Tim_Gu  阅读(260)  评论(0编辑  收藏  举报