Python

轻量级组件

协程

  1. 应用场景
    • 耗时操作
  2. 原理
    • 利用生成器(yield)

代码示例:

from greenlet import greenlet
from time import sleep


def foo():
    for i in range(5):
        print('foo:' + str(i))
        P02.switch()
        sleep(0.3)


def bar():
    for i in range(5):
        print('bar:' + str(i))
        P01.switch()
        sleep(0.3)


if __name__ == '__main__':
    # switch功能类似yield + next,且不会因为生成超过任务本身的生成次数而导致的报错(先断点再生成下一次,阻塞函数)
    P01 = greenlet(foo)  # 创建协程对象
    P02 = greenlet(bar)
    P01.switch()  # 主进程也被断点了(下方的代码不会执行)
    '''
    foo:0
    bar:0
    foo:1
    bar:1
    foo:2
    bar:2
    foo:3
    bar:3
    foo:4
    bar:4
    '''

gevent和monkey

  1. gevent
    • greenlet的升级版(不用手动加switch)
  2. monkey
    • 替换time.sleep,让gevent感觉到阻塞以达到切换

代码示例:

import time
import gevent
from gevent import monkey

monkey.patch_all()  # 任何情况下一般必须置顶(在加载函数前替换,以防兼容性问题,特别是requests)


def foo():
    for i in range(5):
        print('foo:' + str(i))
        time.sleep(0.3)


def bar():
    for i in range(5):
        print('bar:' + str(i))
        time.sleep(0.3)


if __name__ == '__main__':
    P01 = gevent.spawn(foo)  # 创建协程对象及执行任务(当同时运行两个以上的协程对象任务时,根据是否在阻塞状态来实行交替运行)
    P02 = gevent.spawn(bar)
    P01.join()  # 库本身原因,需要主进程让步
    P02.join()  # 可用gevent.joinall([P01,P02]) 代替(实参为可迭代对象)
    '''
    foo:0
    bar:0
    foo:1
    bar:1
    foo:2
    bar:2
    foo:3
    bar:3
    foo:4
    bar:4
    '''