python之路(15)协程(yield)

前言

  线程和进程都是抢占式是使用cpu资源,协程是非抢占式的使用cpu资源,可以认为的去指定程序去使用cpu资源。协程不通过线程而实现程序的并发。但是协程只能在一个进程中执行,无法使用多核,因此多进程+协程是一种很好的方案

  通过使用yield来模拟线程间切换数据的保存

#这是一个生成器
def consumer(name):

    print("--->ready to eat baozi...")
    while True:
        new_baozi = yield
        print("[%s] is eating baozi %s" % (name,new_baozi))
        #time.sleep(1)

def producer():

    r = con.__next__() #consumer对象在yield处挂住,等待传值赋值给new_baozi
    r = con2.__next__() #consumer对象在yield处挂住,等待传值赋值给new_baozi

    n = 0
    while 1:
        time.sleep(1)
        print("\033[32;1m[producer]\033[0m is making baozi %s and %s" %(n,n+1) )
        con.send(n)  #发送数据给yield,将值赋值给new_baozi
        con2.send(n+1) #发送数据给yield,将值赋值给new_baozi
        n +=2


if __name__ == '__main__':

    con = consumer("c1")
    con2 = consumer("c2")
    producer()

###############################
--->ready to eat baozi...
--->ready to eat baozi...
[producer] is making baozi 0 and 1
[c1] is eating baozi 0
[c2] is eating baozi 1
[producer] is making baozi 2 and 3
[c1] is eating baozi 2
[c2] is eating baozi 3
[producer] is making baozi 4 and 5
[c1] is eating baozi 4
[c2] is eating baozi 5
[producer] is making baozi 6 and 7
[c1] is eating baozi 6
[c2] is eating baozi 7
......
例子

 greenlet模块

from greenlet import greenlet

def test1():
    print(12)
    gr2.switch() #切换到test2()处
    print(34)

def test2():
    print(56)
    gr1.switch()  #切换到test1()处
    print(78)
    gr1.switch()  #切换到test1()处

gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr2.switch() #切换到test2()处

###################
56
12
78
34

gevent模块

import gevent
import requests,time

def f(url):
    print('GET: %s' % url)
    resp =requests.get(url) #爬取网站
    data = resp.text
    print('%d bytes received from %s.' % (len(data), url))

#5个爬取操作进行协程的操作
gevent.joinall([
        gevent.spawn(f, 'https://www.python.org/'), #f是函数名,后面是参数
        gevent.spawn(f, 'https://www.yahoo.com/'),
        gevent.spawn(f, 'https://www.baidu.com/'),
        gevent.spawn(f, 'https://www.sina.com.cn/'),
        gevent.spawn(f, 'http://www.xiaohuar.com/hua/'),
])

  通过协程的方式进行爬取网站要比串行的方式进行爬取网站要快,爬取的内容越多,差别越大 

 

posted @ 2019-05-08 21:54  树之下  阅读(213)  评论(0编辑  收藏  举报