• 潭州课堂25班:Ph201805201 并发(协程) 第十五课 (课堂笔记)


    #斐波那契
    def fid(n):
        res = []
        indx = 0
        a = 0
        b = 1
        while indx < n :
            res.append(b)
            a,b = b,a+b
            indx += 1
        return res
    
    print(fid(1000))
    

      

    #  生成器
    def fid(n):
        indx = 0
        a = 0
        b = 1
        while indx < n :
            yield b             #  暂停并返回    跳出函数
            res.append(b)
            a,b = b,a+b
            indx += 1
    
    
    f = fid(10)
    print(f)
    print(next(f))
    

      

    #  生成器
    import time
    
    def fid(n):
        indx = 0
        a = 0
        b = 1
        while indx < n :
            data = yield b             #  暂停并返回    跳出函数
            time.sleep(data)
            a,b = b,a+b
            indx += 1
    
    
    f = fid(10)
    # #   使用 send 前,要 next 下
    # f.__next__()
    # 或者 先 send ( None )
    f.send(None)
    print(f.send(2))
    print(f.send(2))
    print(f.send(2))
    

      

    #  协程 :非抢占式多任务子程序组件
    
    import greenlet     #  pip install greenlet
    
    from greenlet import greenlet
    
    def tast_1():
        print(11111)
        gr2.switch()
        print(22222)
    
    def tast_2():
        print(33333)
        print(44444)
        gr1.switch()
    
    gr1 = greenlet(tast_1)
    gr2 = greenlet(tast_2)
    gr1.switch()            #   调用协程,


    ######

    11111
    33333
    44444
    22222

      

    #  协程   传参
    
    import greenlet     #  pip install greenlet
    
    from greenlet import greenlet
    
    def tast_1():
        print(11111)
        a = gr2.switch()        #  传参
        print(22222)
        print(a)
    
    def tast_2():
        print(33333)
        print(44444)
        gr1.switch(123)          #  传参
    
    gr1 = greenlet(tast_1)
    gr2 = greenlet(tast_2)
    gr1.switch()            #   调用协程,
    
    
    #########
    11111
    33333
    44444
    22222
    123
    

      

     遇到阻塞时自动切换, 

    #  gevent HTTP 请求
    
    from gevent import monkey;monkey.patch_all()       #  猴子补丁
    import gevent
    '''当 greenlet 遇到一个 IO 操作垢时候 ,自动切换到其他的 greenlet'''
    import requests
    # import time
    
    
    def get_res(pn):
        print('开始',pn)
        requests.get('https://www.baidu.com')   #  这里耗时发生阻塞
        # time.sleep(3)
        print('结束',pn)
    
    
        #  gevent.spawn  启动协程
    ta = [gevent.spawn(get_res,i) for i in range(5)]
    # time.sleep(2)
    gevent.joinall(ta)
    # gevent.joinall(ta,timeout=1)
    
    #  spawn   创建一个 gevent 的的协程对象,开始运行,
    #   为什么  ta = [gevent.spawn(get_res,i) for i in range(5)]
    #   不打印,?因为他运行为立马退出,不会打印,
    #   joinall 等待所有 greenlet 执行完毕,
    

      

     如果没有使用猴子补丁

    #  生产者与消费者
    
    import gevent
    import random
    from queue import Queue     #   队列
    q = Queue(2)
    
    def con():                  #   消费者
        while True:
            print(q.qsize())
            iten = q.get()
            print('删除一个数据{}'.format(iten))
    
    
    def pro():                   #   生产者
        while True:
            print(q.qsize())
            iten = random.randint(0,99)
    
            #    如果没有猴子补丁,程序将阻塞在这里,
            q.put(iten)
        
            print('添加一个数据{}'.format(iten))
    
    
    p1 = gevent.spawn(pro)
    c1 = gevent.spawn(con)
    gevent.joinall([p1,c1])    
    

      ########

    0
    添加一个数据32
    1
    添加一个数据22
    2

     在  gevent 有 queue 队列,也可实现相互切换

    在上边代码中引入

    from gevent.queue import Queue

    引入猴子补丁

    from gevent import monkey;monkey.patch_all()#  猴子补丁
    #  生产者与消费者
    
    import gevent
    from gevent import monkey;monkey.patch_all()        #  猴子补丁
    import random
    from queue import Queue     #   队列
    q = Queue(2)
    
    def con():                  #   消费者
        while True:
            print(q.qsize())
            iten = q.get()
            print('删除一个数据{}'.format(iten))
    
    
    def pro():                   #   生产者
        while True:
            print(q.qsize())
            iten = random.randint(0,99)
            q.put(iten)
            print('添加一个数据{}'.format(iten))
    
    
    p1 = gevent.spawn(pro)
    c1 = gevent.spawn(con)
    gevent.joinall([p1,c1])
    

      

    0
    添加一个数据57
    1
    添加一个数据25
    2
    2
    删除一个数据57
    1
    删除一个数据25
    0

    协程,猴子补丁,实现并发服务器

    from gevent import monkey;monkey.patch_all()
    import socket
    import gevent
    
    sever = socket.socket()
    sever.bind(('',10000))
    sever.listen(5)
    print('服务器开启')
    
    def func(conn):
        while True:
            data = conn.recv(1024)
            if data:
                print(data)
            else:break
    
    
    while True:
        conn,addr = sever.accept()
        print(addr)
        gevent.spawn(func,conn)
    

      

  • 相关阅读:
    两个单向链表的第一个公共节点
    c字符输出
    堆排序
    归并排序
    LR中,URL -based script与HTML -based script区别
    loadrunner文本检查点
    Loadrunner集合点Rendezvous知识
    连接池(Connection Pool)技术
    lucene 查询 (转载)
    Lucene + Hadoop 分布式搜索运行框架 Nut 1.0a9转自http://www.linuxidc.com/Linux/2012-02/53113.htm
  • 原文地址:https://www.cnblogs.com/gdwz922/p/9357921.html
Copyright © 2020-2023  润新知