• Python协程


    协程是一种实现并行编程的方法。不同于多线程或者多进程编程,各个协程其实还是在一个线程里运行,只是我们可以控制每个协程什么时候运行,什么时候停止,当一个协程停止时让另外的协程运行,从而达到并行计算的效果。运用协程的优点在于,因为所有的协程其实都是运行在一个线程里,因此它减少了在一个个协程间切换的代价,也不必考虑锁的问题。所以协程实现起来还是比较方便和简单的。
    下面展示一个最简单的Python协程:

    def coroutine():
        print "coroutine"
        x = 1
        n = yield x
        print n,x
    	
    c = coroutine()
    x= c.next()
    c.send(5)
    

    输出如下:

    coroutine
    1
    5 1
    Traceback (most recent call last):
      File "C:PythonScriptcoroutine.py", line 11, in <module>
        c.send(5)
    StopIteration
    

    上面的代码中,首先生成协程对象c。之后需要执行一下c.next,程序会跑到coroutine函数中第一个yield的地方,并将yeild右边的值传给x。之后不断调用send,并将send中传入的参数赋值给n。当函数调用完毕的时候,会触发StopIteration的异常。
    协程对象可以调用close函数,这样就不会触发StopIteration的异常了。

    Python可以通过inspect.getgeneratorstate函数来获取协程的执行状态,该函数会返回下述字符串中的一个:
    'GEN_CREATED':等待执行
    'GEN_RUNNING':正在执行
    'GEN_SUSPENED':在yield表达式处暂停
    'GEN_CLOSE':执行结束

    可以设置一个预激活协程的装饰器,通过该装饰器装饰协程后,就会预先启动next了。

    from functools import wraps
    
    def coroutine(func):
    	@wraps(func)
    	def primer(*args, **kwargs):
    		gen = func(args, kwargs)
    		next(gen)
    		return gen
    	return primer
    

    最后展示一组运用协程实现的生产者消费者模型(其实是廖雪峰官网展示的):

    import time
    
    def consumer():
        r = ''
        while True:
            n = yield r
            if not n:
                return
            print('[CONSUMER] Consuming %s...' % n)
            time.sleep(1)
            r = '200 OK'
    
    def produce(c):
        c.next()
        print "next"
        n = 0
        while n < 5:
            n = n + 1
            print('[PRODUCER] Producing %s...' % n)
            r = c.send(n)
            print('[PRODUCER] Consumer return: %s' % r)
        c.close()
    
    if __name__=='__main__':
        c = consumer()
        produce(c)
    

    输出结果:

    [PRODUCER] Producing 1...
    [CONSUMER] Consuming 1...
    [PRODUCER] Consumer return: 200 OK
    [PRODUCER] Producing 2...
    [CONSUMER] Consuming 2...
    [PRODUCER] Consumer return: 200 OK
    [PRODUCER] Producing 3...
    [CONSUMER] Consuming 3...
    [PRODUCER] Consumer return: 200 OK
    [PRODUCER] Producing 4...
    [CONSUMER] Consuming 4...
    [PRODUCER] Consumer return: 200 OK
    [PRODUCER] Producing 5...
    [CONSUMER] Consuming 5...
    [PRODUCER] Consumer return: 200 OK
    
  • 相关阅读:
    C++ Node template typename T
    C++ BST Insert Print,compile via g++ ,the *.cpp asterisk can represent all the files end with cpp
    springmvc 请求数据 全局过滤器
    spring mvc页面跳转和回写
    Conda 换源
    d2l 安装,提示 "error:Microsoft Visual C++ 14.0 or greater is required.Get it with "Microsoft C++ Build Tools""
    Conda 安装配置
    UI卡顿假死问题
    System.NotSupportedException:“该类型的 CollectionView 不支持从调度程序线程以外的线程对其 SourceCollection 进行的更改。”
    List<T>和ObservableCollection<T>的相互转换
  • 原文地址:https://www.cnblogs.com/wickedpriest/p/12214340.html
Copyright © 2020-2023  润新知