Python generator 构建协程,实现异步编程(使用yield构建消息处理者和消息创造者)

发布时间 2023-05-29 10:40:22作者: sqmw

协程的定义理解

Python 协程可以在单个处理机或多个处理机上运行,这取决于具体实现方式。在 Python 中,主要有两种协程实现方式:生成器协程和 asyncio 协程。

生成器协程只能在单个处理机上运行,因为生成器协程是通过生成器函数实现的,而生成器函数在单个线程中执行。生成器协程也称为“微线程”。

asyncio 协程是由 asyncio 模块提供的,它可以在多个处理机上运行,并且可以实现并发性。asyncio 协程是在事件循环(event loop)中运行的,事件循环负责协调多个协程的执行,以便实现并发性。asyncio 协程是 Python 3.4 及更高版本中引入的。

生成器协程的实现

代码

# 消息处理者
def msg_handler():
    r = "handler处理返回结果,首次的返回对应的是对协程的初始化,让协程进入就绪状态"

    while True:
        # 只有使用下面的 lambda 才能接收在同一个表达式里面的参数 m 如果需要复杂的处理,则可以借助lambda表达式,在调用复杂的处理函数
        m = yield lambda: f"接收的消息 -> {m},处理结果 -> {m * 10}, 返回的消息 -> {r}"  # 这里的 yield 后面的lambda表达式对应的依然是返回值,这个表达式接收了m
        # ,封装了对m的处理过程,但是 m 表示的是 接收道德消息
        print(f"接收到的数据: {m}")
        if m is None:
            break


# 消息创造者
def msg_creator(handler: msg_handler):
    print(handler.send(None))  # send是对 next 的封装,这里的send(None)可以使用next(
    # handler)代替,这里我们send的消息,handler没有接收,但是在handler里面给我们返回了值,
    # 这里的send(None)是对handler的初始化,让handler进去就绪状态,防止没必要的CPU等的资源浪费
    i = 0
    while i < 5:
        r = handler.send(i)
        i += 1
        print(f"消息创造者接收道德消息处理返回结果: {r()}")
    handler.close()


msg_creator(msg_handler())

总结

上面的代码展示了一个简单的Python协程示例。代码中包含了两个函数:一个信息处理者函数和一个信息创造者函数。信息处理者函数首先会接收一个初始化消息,然后会进入一个无限循环,从生成器中接收消息并对其进行处理。处理结果将会作为一个带返回值的lambda表达式,被send回生成器。信息创造者函数通过调用信息处理者函数的生成器(即msg_handler())来开启这个协程。在此过程中,信息创造者会通过send将消息发送给信息处理者。信息处理者通过处理消息来产生一个返回值,并把返回值送回信息创造者。

在这个示例代码中,协程用于实现消息的异步处理。使用协程实现异步处理可以避免线程切换和上下文切换的开销,从而提高程序的执行效率。另外,协程能够在单线程中实现多个任务的并发执行,也使得编写高效并发的任务变得更加容易。