• 什么是协程,Python协程基本用法

    协程(coroutine)可以理解为是线程的优化,又称之为轻量级进程。它是一种比线程更节省资源、效率更高的系统调度机制。

    协程具有这样的特点,即在同时开启的多个任务中,一次只执行一个,只有当前任务遭遇阻塞,才会切换到下一个任务继续执行。这种机制可以实现多任务的同步,又能够成功地避免线程中使用锁的复杂性,简化了开发。

    早先的协程是使用生成器关键字 yield 来实现的,代码特别复杂难懂。自从 Python 3.5之后,确定了协程的语法,使得创建协程的方式得到改善。Python 中,能够实现协程的模块有多个,如 asyncio、tornado 或 gevent。

    这里以 asyncio 为例,先来了解一下创建协程所用到的概念:

    • event_loop(事件循环):是一个协程处理函数的调用机制。程序会开启一个无限循环,当事件发生时,调用相应的协程函数。
    • coroutine(协程对象):指一个使用 async 关键字来定义的函数。调用该函数,会返回一个协程对象。该协程对象就是一个处于挂起状态的协程函数,需要注册到事件循环 event_loop 中,由事件循环 event_loop 进行调用。
    • task 任务:是对协程的进一步封装。
    • future:等同于 task,代表执行任务的结果。
    • async/await 关键字:Python 3.5 中用于定义协程的关键字,其中 async 用于定义一个协程,await 用于挂起阻塞的异步调用接口。

    Python协程的基本用法

    下面通过代码演示最基本的协程用法:

    # 导入asyncio模块
    import asyncio
    #定义协程处理函数
    async def demo(x):
        print(x)
        r = await asyncio.sleep(1)
        print(x,"again")
    #生成协程对象,并传入 hello
    coroutine = demo("C")
    loop = asyncio.get_event_loop()
    try:
        #将协程注册到实现事件循环对象中,并开始运行。
        loop.run_until_complete(coroutine)
    finally:
        #程序结束关闭事件循环对象
        loop.close()

    运行结果为:

    C
    C again

    注意,以上程序代码只能用在 Python 3.5 以及后续版本。因为 async 和 await 关键字是 3.5 版本才新加入。并且,在 Python 3.7 版本及后续版本中,可以使用 asyncio.run(coroutine) 代替第10~16行的代码,它们是完全等价的。

    上面的代码体现了实现协程的基本步骤:

    1. 使用 async 关键字定义协程处理函数;
    2. 生成协程对象;
    3. 调用 asyncio 中的 get_event_loop 函数获得事件循环对象;
    4. 调用事件循环对象的 run_until_complete 方法,运行协程处理函数。

    协程VS线程

    与线程相比,协程封装的内容更多,实现起来更容易。

    开发者使用协程会少考虑很多事情。在默认情况下应优先使用协程。但是有一个特点要注意,协程是多任务的顺序执行,只有当前任务挂起后,才会切换到其他任务来执行;而线程是以 CPU 轮换的方式执行。

    因此,两者的运行机制有着本质上的区别,这使得二者都不可被代替。也就是说,如果业务需求要每个并行线程的处理进度也要同步,那么使用协程将不是一个很好的方案。在实际工作中,应根据业务需要来灵活运用线程或协程。

更多...

加载中...