• Python--Demo18--异步IO之协程


    协程:

    使用一个线程来实现异步操作的。它相对于多线程执行效率高,不存在线程切换;此外协程不牵扯多线程中锁的机制,所以不必考虑加锁这些复杂操作。

    协程是通过generator来实现的,就是yield关键字和send()函数的使用。

    生成器的yield关键字:

    yield关键字可以将值(信息)返回,同时在信息返回后使程序停留在当前行。

    >>> def test():
    ...     number=1
    ...     while True:
    ...             number*=2
    ...             yield number
    ...             print('yield下面的代码')
    ...
    >>> t=test()
    >>> t
    <generator object test at 0x000001E372BDA5F0>
    >>> type(t)
    <class 'generator'>
    >>> next(t)
    2
    >>>
    >>> next(t)
    yield下面的代码
    4
    >>> next(t)
    yield下面的代码
    8
    >>> next(t)
    yield下面的代码
    16

    生成器的send()函数:

    yield还可以接收调用者传递过来的信息:通过sned()函数,将值(消息)传递给生成器。生成器通过yield前面的变量来接收传递过来的值。

    >>> def tst():
    ...     number=1
    ...     while True:
    ...             pam=yield number
    ...             print('yield下面代码')
    ...             print('调用者传递过来的值:',pam)
    ...
    >>> tt=tst()
    >>> tt.send(None)
    1
    >>> tt.send(None)
    yield下面代码
    调用者传递过来的值: None
    1
    >>> tt.send(111)
    yield下面代码
    调用者传递过来的值: 111
    1

    说明:send()函数和next()函数都推动生成器向下执行,next()函数仅仅是接收了yield右边的返回值;而send()函数则可以使调用者给生成器发消息。

    生成器的close()函数:

    调用close()函数就可以关闭生成器,接下来next()函数再应用于生成器就会提示生成器已停止的信息

    >>> def test():
    ...     number=1
    ...     while True:
    ...             number*=2
    ...             yield number
    ...             print('yield下面的代码...')
    ...
    >>> gen=test()
    >>> next(gen)
    2
    >>> next(gen)
    yield下面的代码...
    4
    >>> next(gen)
    yield下面的代码...
    8
    >>> gen.close()
    >>> next(gen)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration

    协程:

    通过下面一个消费者和生产者的例子,我们实现一下,生产者生产之后消费者立马消费掉,来进一步了解协程。

    注意:必须在调用send()前,启动生成器。启动生成器可以是next(生成器)或者生成器.send(None),让生成器执行到第一个yield处。之后就可以不断使用send()传入值了。

    def consumer():
        r = ''
        while True:
            n = yield r  # yield 后面的r是返回给调用者的值,yield前面的 n 用来接收调用者通过send函数传过来的值
            if not n:  # 如果n是None,就结束该函数,因为None代表还没有生产出来产品
                print('consumer即将结束')
                return
            print('消费者正在消费%s...' % n)
            r = '200 OK'
    
    
    def produce(c):
        print('send返回值为: ', c.send(None))
        n = 0
        while n < 5:
            n = n + 1
            print('生产者生产了%s...' % n)
            r = c.send(n)  # 生产出来就去给消费者
            print('生产者接收消费者返回的信息:%s' % r)
        c.close()
    
    
    c = consumer()
    produce(c)

    结果:

    send返回值为:  
    生产者生产了1...
    消费者正在消费1...
    生产者接收消费者返回的信息:200 OK
    生产者生产了2...
    消费者正在消费2...
    生产者接收消费者返回的信息:200 OK
    生产者生产了3...
    消费者正在消费3...
    生产者接收消费者返回的信息:200 OK
    生产者生产了4...
    消费者正在消费4...
    生产者接收消费者返回的信息:200 OK
    生产者生产了5...
    消费者正在消费5...
    生产者接收消费者返回的信息:200 OK

    说明:整个过程无锁,一个线程使produce()和consumer()完成协作。

  • 相关阅读:
    BUAA OO Unit1 表达式求导
    中介者模式
    命令模式
    观察者模式
    解释器模式
    策略模式
    迭代器模式
    模板方法模式
    代理模式
    桥接模式
  • 原文地址:https://www.cnblogs.com/bigbosscyb/p/12394744.html
Copyright © 2020-2023  润新知