【问题标题】:How can I schedule a task with asyncio to run in executor?如何使用 asyncio 安排任务在执行程序中运行?
【发布时间】:2018-05-04 05:14:10
【问题描述】:

我一直在使用 asyncio 进行并发,但是我遇到了问题。我需要使用 asyncio 安排一个任务,但它是阻塞的,所以我想使用 concurrent.futures 中的线程池在执行器中执行它。

我见过这样的例子,安排任务:

now = loop.time()
loop.call_at(now + 60, callback, arg, loop)

像这样在执行器中运行任务:

blocking_tasks = [
    loop.run_in_executor(executor, blocks)
    for i in range(6)
]
completed, pending = await asyncio.wait(blocking_tasks)

但是我怎样才能安排一个阻塞任务在执行器中运行呢?

【问题讨论】:

    标签: python threadpool python-asyncio


    【解决方案1】:

    run_in_executor返回一个future,所以你不能和call_at一起使用,这需要一个普通的函数。但是,您可以使用asyncio.sleep() 轻松推迟执行:

    async def my_task():
        await asyncio.sleep(60)
        result = await loop.run_in_executor(None, fn)
        ...
    
    taskobj = loop.create_task(my_task())
    

    这样做的好处是create_task创建的任务在睡眠时可以是canceled。此外,您可以从my_task() 返回一个有用的值,并使用await taskobj、调用taskobj.result()loop.run_until_complete(taskobj) 获取它。

    【讨论】:

      【解决方案2】:

      您可以为此创建一个这样的包装器。

      def run_in_async_loop(f):
          @functools.wraps(f)
          async def wrapped(*args, **kwargs):
              loop = asyncio.get_running_loop()
              return (await loop.run_in_executor(None, f(*args, **kwargs)))
          return wrapped
      

      【讨论】:

      • ) 添加到第一行return 以防止语法错误。
      猜你喜欢
      • 2019-06-06
      • 2018-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多