Python中协程间通信的方式有哪些?

在 Python 中,协程间的通信主要依赖于以下几种方式:

1. asyncio.Queue

asyncio.Queue 是 Python asyncio 库提供的一个线程安全的队列,用于在协程之间传递数据。与常规的队列类似,但它支持异步操作,即可以在协程内等待队列中的数据。

示例:

python 复制代码
import asyncio

async def producer(queue):
    for i in range(5):
        await queue.put(i)
        print(f"Produced: {i}")
        await asyncio.sleep(1)

async def consumer(queue):
    while True:
        item = await queue.get()
        if item is None:  # 用 None 表示终止信号
            break
        print(f"Consumed: {item}")
        await asyncio.sleep(2)

async def main():
    queue = asyncio.Queue()
    await asyncio.gather(producer(queue), consumer(queue))

asyncio.run(main())

2. asyncio.Event

asyncio.Event 是一个简单的同步原语,允许一个协程等待某个事件的发生,另一个协程则负责设置该事件。通常用于通知其他协程某些状态发生变化。

示例:

python 复制代码
import asyncio

async def waiter(event):
    print("Waiting for event...")
    await event.wait()  # 阻塞直到事件被触发
    print("Event occurred!")

async def setter(event):
    await asyncio.sleep(2)
    print("Setting event!")
    event.set()  # 设置事件

async def main():
    event = asyncio.Event()
    await asyncio.gather(waiter(event), setter(event))

asyncio.run(main())

3. asyncio.Condition

asyncio.Condition 类似于线程中的 Condition,允许一个或多个协程等待某个条件的变化。它可以与锁结合使用。

示例:

python 复制代码
import asyncio

async def consumer(condition, shared_data):
    async with condition:
        while shared_data["item"] is None:
            await condition.wait()  # 等待条件
        print(f"Consumed: {shared_data['item']}")
        shared_data["item"] = None

async def producer(condition, shared_data):
    await asyncio.sleep(1)
    async with condition:
        shared_data["item"] = "Apple"
        condition.notify()  # 通知等待的协程
        print(f"Produced: {shared_data['item']}")

async def main():
    shared_data = {"item": None}
    condition = asyncio.Condition()
    await asyncio.gather(producer(condition, shared_data), consumer(condition, shared_data))

asyncio.run(main())

4. asyncio.Semaphore

asyncio.Semaphore 是一个计数信号量,控制并发访问的协程数目。适用于限制协程的并发数量。

示例:

python 复制代码
import asyncio

async def task(sem):
    async with sem:
        print("Task started")
        await asyncio.sleep(1)
        print("Task completed")

async def main():
    sem = asyncio.Semaphore(2)  # 最多同时运行2个协程
    tasks = [task(sem) for _ in range(5)]
    await asyncio.gather(*tasks)

asyncio.run(main())

5. asyncio.Streams (StreamReader 和 StreamWriter)

StreamReaderStreamWriter 是用于网络通信的流接口,适用于两个协程之间通过网络协议传输数据的场景。尽管它们主要用于处理网络 I/O,但也可以用于在协程之间传输数据。

示例:

python 复制代码
import asyncio

async def echo(reader, writer):
    data = await reader.read(100)
    message = data.decode()
    addr = writer.get_extra_info('peername')
    print(f"Received {message} from {addr}")

    print("Send: %r" % message)
    writer.write(data)
    await writer.drain()

    print("Closing the connection")
    writer.close()

async def main():
    server = await asyncio.start_server(
        echo, '127.0.0.1', 8888)

    addr = server.sockets[0].getsockname()
    print(f'Serving on {addr}')

    async with server:
        await server.serve_forever()

asyncio.run(main())

6. asyncio.Future

asyncio.Future 类似于 Promise,它表示一个尚未完成的操作。一个协程可以将其结果存储在 Future 对象中,而其他协程可以等待该 Future 对象完成。

示例:

python 复制代码
import asyncio

async def set_future(future):
    await asyncio.sleep(1)
    future.set_result('Hello from Future!')

async def get_future(future):
    result = await future
    print(f"Got result: {result}")

async def main():
    future = asyncio.Future()
    await asyncio.gather(set_future(future), get_future(future))

asyncio.run(main())

这些通信方式各有其特定的用途,可以根据不同的场景选择合适的方式来进行协程间的通信。

相关推荐
辉视广播对讲15 小时前
医院IPTV,让医疗服务更有温度
网络·人工智能
Tim风声(网络工程师)15 小时前
光功率计中的红光(光衰测试设备)的使用
运维·网络
jieyucx15 小时前
Go语言深度解剖:Map扩容机制全解析(增量扩容+等量扩容+渐进式迁移)
开发语言·后端·golang·map·扩容策略
YJlio16 小时前
7.4.5 Windows 11 企业网络连接与网络重置实战:远程访问、本地策略与故障恢复
前端·chrome·windows·python·edge·机器人·django
脏脏a16 小时前
【C++模版】泛型编程:代码复用的终极利器
开发语言·c++·c++模版
island131416 小时前
【C++仿Muduo库#3】Server 服务器模块实现上
服务器·开发语言·c++
散峰而望16 小时前
【算法竞赛】C/C++ 的输入输出你真的玩会了吗?
c语言·开发语言·数据结构·c++·算法·github
小龙报16 小时前
【C语言】内存里的 “数字变形记”:整数三码、大小端与浮点数存储真相
c语言·开发语言·c++·创业创新·学习方法·visual studio
深耕AI16 小时前
【VS Code避坑指南】点击Python图标提示“没有Python环境”,选择安装uv后这堆输出到底是什么意思?
开发语言·python·uv
第一程序员16 小时前
Rust生命周期管理实战指南:从困惑到掌握
python·github