Python_协程

  • 一些博客

https://www.liaoxuefeng.com/wiki/1016959663602400/1017968846697824#0
https://www.liujiangblog.com/course/python/83
https://docs.python.org/3/reference/datamodel.html#coroutines
https://www.jianshu.com/p/b5e347b3a17c
https://segmentfault.com/a/1190000038241863

  • Coroutine(定义)
    协程,又称微线程,英文名Coroutine,是运行在单线程中的“并发”,协程相比多线程的一大优势就是省去了多线程之间的切换开销,获得了更高的运行效率。
  • 其实可以理解为一种用户态特殊的程序调用。特殊的是在执行过程中,在子程序(或者说函数)内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。
  • 两个特征:
  1. 可中断,这里的中断不是普通的函数调用,而是类似CPU的中断,CPU在这里直接释放转到其他程序断点继续执行。
  2. 可恢复,等到合适的时候,可以恢复到中断的地方继续执行,至于什么是合适的时候,我们后面再探讨。
  • 和进程线程的区别
  1. 进程是操作系统资源分配的基本单位,线程是操作系统调度和执行的最小单位。拆开来说,进程是程序的启动实例,拥有代码和打开的文件资源、数据资源、独立的内存空间。线程从属于进程,是程序的实际执行者,一个进程至少包含一个主线程,也可以有更多的子线程,线程拥有自己的栈空间。无论是进程还是线程,都是由操作系统所管理和切换的。
  2. 进程和线程的切换完全是用户无感,由操作系统控制,从用户态到内核态再到用户态。而协程的切换完全是程序代码控制的,在用户态的切换,就像函数回调的消耗一样,在线程的栈内即可完成。
  • 协程简单demo
def consumer():
    r = ''
    while True:
        n = yield r
        if not n:
            return
        print('[CONSUMER] Consuming %s...' % n)
        r = '200 OK'


def produce(c):
    c.send(None)
    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()


c = consumer()
produce(c)

# consumer()函数是一个生成器,当c.send(None)时,会向生成器内部的yield语句发送数据。
# 此时yield语句不再只是yield xxxx的形式,还可以是var = yield xxxx的赋值形式。它同时具备两个功能,
# 一是暂停并返回函数,二是接收外部send()方法发送过来的值,重新激活函数,并将这个值赋值给var变量!
  • n = yield r
    包含了3个步骤:
  1. 向函数外抛出(返回)r
  2. 暂停(pause),等待next()或send()恢复
  3. 赋值n = MockGetValue(). 这个MockGetValue()是假想函数,用来接收send()发送进来的值
  • asyncio
import asyncio

import time

now = lambda: time.time()


async def do_some_work(x):
    print('Waiting: ', x)

    await asyncio.sleep(x)
    return 'Done after {}s'.format(x)

start = now()

coroutine1 = do_some_work(1)
coroutine2 = do_some_work(2)
coroutine3 = do_some_work(4)

tasks = [
    asyncio.ensure_future(coroutine1),
    asyncio.ensure_future(coroutine2),
    asyncio.ensure_future(coroutine3)
]

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

for task in tasks:
    print('Task ret: ', task.result())

print('TIME: ', now() - start)


OUTPUT:

Waiting:  1
Waiting:  2
Waiting:  4
Task ret:  Done after 1s
Task ret:  Done after 2s
Task ret:  Done after 4s
TIME:  4.0169126987457275

Process finished with exit code 0

你可能感兴趣的:(Python,python)