gevent及greenlet实现协程

2019-10-21  本文已影响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'))
上一篇下一篇

猜你喜欢

热点阅读