如何使用asyncio计划​​任务以在执行程序中运行?

时间:2018-05-04 05:14:10

标签: python threadpool python-asyncio

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

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

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)

但是如何安排阻塞任务在执行程序中运行?

2 个答案:

答案 0 :(得分:2)

run_in_executor会返回未来,因此您无法将其与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)获取该值。

答案 1 :(得分:0)

我们可以为此创建一个包装器吗?

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