• 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("33[32;1m[producer]33[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/'),
    ])
    

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

     

  • 相关阅读:
    [网络流24题] 最小路径覆盖问题
    [P2664] 树上游戏
    [ZROI #316] ZYB玩字符串
    [Codeforces #172] Tutorial
    [网络流24题]方格取数
    Python 全栈开发:python函数进阶
    Python 全栈开发:python函数基础
    Python 全栈开发:python文件处理
    Python 全栈开发:python字符编码
    Python 全栈开发:python字典dict
  • 原文地址:https://www.cnblogs.com/shuzhixia/p/10830736.html
Copyright © 2020-2023  润新知