由浅入深掌握Python异步协程间通信方式

1、异步协程间通信方式类型

协程(Coroutine) 是异步编程中的基本代码单元。多个协程通常并发执行以提高运行效率。经常遇到的情形,协程之间需要通信,如多个协程需要访问修改同1个数据,或者1个协程需要等待另1个协程,等等。 对于协程之间通信需求,标准库asyncio模块除了提供了异步队列(asyncio.queue) 用于协程间数据传递, 还提供了几种同步通信对象。

同步原语 说明
Lock 同步锁,同时只允许 1个用户访问资源
Semaphore 信号量,同时允许多个用户访问资源
Event 信号事件机制,同时允许 1个用户访问资源
Condition 类似于Lock与Event的组合
Barrier 用于wait多个子线程并行运行

2、使用异步队列通信

主线程向协程,协程之间通信最好的方式是 queue, 与标准库的Queue模块不同,asyncio.Queue模块支持 async/await 从队列存取数据。

1)Asyncio.Queue 主要方法与属性如下;

  • get()方法: 注意应该与await 一起使用, data = await queue.get(), 否则会报错。如果不在协程函数中读数据,使用 get_nowait() 方法。
  • put()方法,协程函数中,await queue.put(data), 非协程函数,用 queue.put_nowait(data)
  • join()方法: 阻塞queue,直到队列中的所有元素都被取出并处理。
    • 当1个元素被添加到队列后,unfinished tasks 总数增加
    • 当1个消费者协程调用 task_done()时,表示其取出了1个元素,与该元素相关的工作已经完成,unfinished task 减少1。
    • 当unfinished task降为零, join()将解除阻塞。
  • 其它方法:
    qsize(), full(), empty(),maxsize() 与标准库queue使用相同。

2)示例

import asyncio
import random

async def worker(name, queue):
    while not queue.empty():
        n =await queue.get()
        print(f"worker get {
     
     n} from queue")
        await asyncio.sleep(0.5)
        queue.task_done() # 处理完1个元素,应发送task_done()

async def main():
    # Create a queue that we will use to store our "workload".
    qu = asyncio.Queue()
    for _ in range(10):
        qu.put_nowait(random.randrange(1,100,1))
    
    task = asyncio.create_task(worker("worker",qu))
    qu.join()  # 阻塞队列,直到unfinished task 为0
    # 生成异步任务集合
    await asyncio.gather(task,return_exceptions=True)
    print(qu.qsize())

if __name__ == "__main__":
    asyncio.run(main())

3、同步通信

用于同步通信的对象包括: Lock, Event, Condition, Smartphore,Barrier, 与多线程使用方式基本相同。

1) Lock同步锁

用于控制多个协程访问同1个资源,避免同抢
通过示例了解其用法:


import asyncio
import random

counter = 0    # 全局变量

async def foo(num, lock):
    await asyncio.sleep(1 + random.random())
    await lock.acquire()  # 获取锁
    try:
        global counter
        print("coro foo is running, get ", num)
        counter += 1
        print("counter: "<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值