• Python 之并发编程之协程


    一.协程

    '''

    def gen():

        for i in range(10):

            yield i

    # 初始化生成七函数 返回生成器对象,简称生成器

    mygen = gen()

    for i in mygen:

        print(i)

    '''

    # (1) 用协程改写成生产者消费者

    '''

    def producer():

        for i in range(100):

            yield i

    def consumer():

        g = producer()

        for i in g:

            print(i)

    '''

    # (2) 协程的具体实现

    from greenlet import greenlet

    import time

    '''

    switch 利用它进行任务的切块,一般在阻塞的时候切块

    只能默认手动切换

    缺陷: 不能规避io,不能自动实现遇到阻塞就切换

    '''

    """

    def eat():

        print("eat one")

        # 手动切换play这个协程中

        g2.switch()

        time.sleep(1)

        print("eat two")

    def play():

        print("play one")

        time.sleep(1)

        print("play two")

        g1.switch()

    g1 = greenlet(eat)

    g2 = greenlet(play)

    g1.switch()

    '''

    eat one

    play one

    play two

    eat two

    '''

    """

    # (3) 缺陷:gevent不能够识别time.sleep 是阻塞

    """

    import gevent

    # gevent 其中有一个spawn 类似于switch ,也是切换任务的

    import time

    def eat():

        print("eat one")

        time.sleep(1)

        print("eat two")

    def play():

        print("play one")

        time.sleep(1)

        print("play two")

    # 利用gevent 创建协程对象g1

    g1 = gevent.spawn(eat)

    #利用gevent创建协程对象g2

    g2 = gevent.spawn(play)

    # 协程的阻塞是join 等待当前协程执行完毕之后,再向下执行

    g1.join()  #阻塞直到g1协程执行完毕

    g2.join()  #阻塞直到g2协程执行完毕

    print("主线程执行完毕")

    """

    # (4) 进阶 用gevent.sleep 来取代time.sleep()

    '''

    import gevent

    def eat():

        print("eat one")

        gevent.sleep(1)

        print("eat two")

    def play():

        print("play one")

        gevent.sleep(1)

        print("play two")

    g1 = gevent.spawn(eat)

    g2 = gevent.spawn(play)

    g1.join()

    g2.join()

    print("主线程执行完毕")

    '''

    # (5) 终极解决识别问题

    # spawn gevent spawn 遇到阻塞会自动切换协程任务

    from gevent import monkey

    # patch_all 下面引入的所有模块中的阻塞识别出来

    monkey.patch_all()

    import time

    import gevent

    def eat():

        print("eat one")

        time.sleep(1)

        print("eat two")

    def play():

        print("play one")

        time.sleep(1)

        print("play two")

    g1 = gevent.spawn(eat)

    g2 = gevent.spawn(play)

    g1.join()

    g2.join()

    print("主进程执行结束...")

    二.协程例子

  • 相关阅读:
    Cron表达式说明
    exe4j 使用记录(二):jar打包exe
    exe4j 使用记录(一):下载、安装及注册
    Sublime Text3添加右键
    jenkins 入门教程
    Visual Studio设置字体及护眼背景色
    Visual Studio 设置C#语言代码格式
    Visual Studio 常用快捷键
    Maven中使用本地JAR包
    oracle 查看锁表及解锁的语句
  • 原文地址:https://www.cnblogs.com/hszstudypy/p/11294608.html
Copyright © 2020-2023  润新知