美文网首页
gevent及greenlet实现协程

gevent及greenlet实现协程

作者: 陈忠俊 | 来源:发表于2019-10-21 23:45 被阅读0次

    1. 一个用yield实现的简单send调用

    import time
    import random
    
    def fib(n, start):
        index = 0
        a = 0
        b = 1
        start = start # 循环次数
        while index < n:
            sleep_cnt = yield start # 通过send获取睡眠时间
            print("let me think {} seconds".format(sleep_cnt))
            time.sleep(sleep_cnt)
            a, b = b, a + b
            index += 1
            start -= 1
    print("test yield send")
    N = 20
    sfib = fib(N, 11)
    res = next(sfib) # 启动send调用
    while True:
        print(res)
        try:
            res = sfib.send(random.uniform(0, 0.5) * 10)
        except StopIteration:
            break
    

    2. 下面的这个算是一个简单的协程

    #! /usr/bin/env python3
    # -*- coding: utf-8 -*-
    import logging
    import time
    logging.basicConfig(level = logging.DEBUG)
    log = logging.getLogger(__file__)
    
    def consumer():
        log.info("consumer start")
        while True:
            flag = yield
            log.info("running now: %s" %flag)
            time.sleep(1)
    
    def producer(model):
        model.send(None) #启动协程
        for i in range(10):
            log.info("producer running...")
            model.send(i)
    
    if __name__ == "__main__":
        aa = consumer()
        producer(aa)
    

    3. greenlet实现协程

    from greenlet import greenlet
    import time
    
    def eat():
        print("Eating start...")
        time.sleep(1)
        g2.switch()
        print("Eating end.")
        g2.switch()
    
    def play():
        print("We are playing...")
        time.sleep(1)
        g1.switch()
        print("Stop playing.")
    
    if __name__ == "__main__":
        g1 = greenlet(eat)
        g2 = greenlet(play)
        g1.switch()
    

    对应的输出

    Eating start...
    We are playing...
    Eating end.
    Stop playing.
    

    4. gevent实现协程

    import gevent
    from gevent import monkey
    monkey.patch_all()
    
    import time
    
    def eat():
        print("Eating start...")
        time.sleep(5)
        print("Eating done!")
    
    def paly():
        print("We are playing...")
        time.sleep(5)
        print("Stop playing.")
    
    g1 = gevent.spawn(eat)
    g2 = gevent.spawn(paly)
    g1.join()
    g2.join()
    

    在执行这一段代码的时候,等待的时间将是5秒钟。程序的执行时间5秒多。当eat函数执行到sleep的时候,协程将切换到play函数。5秒钟后两个函数同时执行最好一句代码。

    下面的是协程版的简易socketclient
    server.py:

    from gevent import monkey; monkey.patch_all()
    import socket
    import gevent
    def talk(conn):
        conn.send(b'hello')
        print(conn.recv(1024).decode('utf-8'))
        conn.close()
    
    sock = socket.socket()
    sock.bind(('127.0.0.1', 8888))
    sock.listen(5)
    while True:
        conn, addr = sock.accept()
        gevent.spawn(talk, conn)
    sock.close()
    

    client.py

    import socket
    
    sock = socket.socket()
    sock.connect(('127.0.0.1', 8888))
    print(sock.recv(1024).decode('utf-8'))
    msg = input(">>>")
    sock.send(msg.encode('utf-8'))
    

    相关文章

      网友评论

          本文标题:gevent及greenlet实现协程

          本文链接:https://www.haomeiwen.com/subject/nuffvctx.html