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())

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

相关推荐
数据智能老司机4 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机5 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机5 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机5 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i5 小时前
drf初步梳理
python·django
每日AI新事件5 小时前
python的异步函数
python
这里有鱼汤6 小时前
miniQMT下载历史行情数据太慢怎么办?一招提速10倍!
前端·python
databook16 小时前
Manim实现脉冲闪烁特效
后端·python·动效
程序设计实验室16 小时前
2025年了,在 Django 之外,Python Web 框架还能怎么选?
python
倔强青铜三17 小时前
苦练Python第46天:文件写入与上下文管理器
人工智能·python·面试