【问题标题】:How to use asyncio for asynchronous handler?如何将 asyncio 用于异步处理程序?
【发布时间】:2022-12-07 01:22:51
【问题描述】:

我有一个不断产生一些对象的函数,比如说每秒 1 个,还有一个工作 2 秒并处理这些对象的处理程序。例如:


from time import sleep
import asyncio
from datetime import datetime

def generator():
    i = 0
    while True:
        yield i
        i += 1
        sleep(1)

def handler(number):
    sleep(2)
    if number % 2 == 0:
        print(str(number) + ' is even')
    else:
        print(str(number) + ' is odd')


for number in generator():
    handler(number)

因此,例如程序启动后 6 秒打印“2 是偶数”。如何使用 asyncio 将此时间减少到 4 秒(生成器 2 秒 + 处理程序 2 秒)?我需要设置数字的异步处理。

【问题讨论】:

    标签: python asynchronous python-asyncio


    【解决方案1】:

    您需要在此处进行一些更改:

    1. 你的generator目前是一个“生成器”,把它改成"asynchronous generator"这样你就可以使用async for了。这样它就可以将控制权交还给事件循环。

    2. asyncio库中使用sleep的异步版本:asyncio.sleeptime.sleep不配合其他任务。

    3. 将您的 handler 同步功能更改为“协程”。

      import asyncio
      
      
      async def generator():
          i = 0
          while True:
              yield i
              i += 1
              await asyncio.sleep(1)
      
      
      async def handler(number):
          await asyncio.sleep(2)
          if number % 2 == 0:
              print(str(number) + " is even")
          else:
              print(str(number) + " is odd")
      
      
      async def main():
          async for number in generator():
              asyncio.create_task(handler(number))
      
      
      asyncio.run(main())
      

      现在,您的第一个任务是mainasyncio.run() 自动将其创建为任务。然后当这个任务运行时,它通过generator()异步迭代。然后为每个数字接收值,您从 handler 协程中创建一个新任务。

      这样睡眠时间就会重叠。当它等待新号码 1 秒时,它实际上也等待 handler() 1 秒。那么在收到号码的时候,handler()任务的1秒已经过去了,只需要1秒。

      如果需要,您可以查看任务数:

      async def main():
          async for number in generator():
              print(f"Number of all tasks: {len(asyncio.all_tasks())}")
              asyncio.create_task(handler(number))
      

      因为每个处理程序睡眠2秒,而您的数字生成器睡眠1秒,您会看到在每次迭代中2任务都存在于事件循环中。在generator协程中将await asyncio.sleep(1)更改为await asyncio.sleep(0.5),你会看到4任务在每次迭代中都在事件循环中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-23
      • 1970-01-01
      • 2015-06-07
      • 1970-01-01
      • 1970-01-01
      • 2020-10-21
      相关资源
      最近更新 更多