Параллельный вызов асинхронной функции в Python 3.6 - PullRequest
0 голосов
/ 27 августа 2018

У меня есть скрипт, в котором функция Slow и Fast обрабатывает один и тот же массив глобальных объектов. Функция Slow предназначена для заполнения массива новыми объектами на основе ресурсоемких вычислений, а функция Fast предназначена только для итерации существующих объектов в массиве и их обслуживания / отображения. Функция Slow должна запускаться только каждые несколько секунд, но функция Fast должна запускаться как можно чаще. Я пытался использовать asyncio и sure_future, вызывая процесс Slow, но в результате функция Fast (main) работала до тех пор, пока я ее не остановил, и только в конце была вызвана функция Slow. Мне нужно, чтобы функция Slow запускалась в том случае, если она вызывается в фоновом режиме, и завершается всякий раз, когда это возможно, но без блокировки вызова функции Fast. Не могли бы вы мне помочь? Спасибо!

Пример того, что я попробовал:

import asyncio
variable = []

async def slow():
    temp = get_new_objects() #resource intensive
    global variable
    variable = temp

async def main():
    while True: #Looping
        if need_to_run_slow: #Only run sometimes
            asyncio.ensure_future(slow())

        do_fast_stuff_with(variable) #fast part

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close()

1 Ответ

0 голосов
/ 27 августа 2018

asyncio.ensure_future(slow()) только планирует slow() для запуска на следующем проходе цикла событий. Поскольку ваш цикл while не ожидает ничего, что может фактически блокировать, вы не даете шансу события возможность работать.

Вы можете обойти эту проблему, добавив await asyncio.sleep(0) после вызова быстрой функции:

async def main():
    while True:
        if need_to_run_slow:
            asyncio.ensure_future(slow())
        await asyncio.sleep(0)
        do_fast_stuff_with(variable)

Неактивный режим сна гарантирует, что на каждой итерации цикла while (и между запусками "быстрой" функции ") есть шанс для заранее запланированного slow() для достижения прогресса.

Однако ваш slow() тоже не ждет, поэтому весь его код будет выполняться за одну итерацию, что делает вышеприведенный эквивалент гораздо более простым:

def main():
    while True:
        slow()  # slow() is an ordinary function
        do_fast_stuff_with(variable)

Пример кода, более близкий к вашему реальному варианту использования, вероятно, приведет к более непосредственному использованию ответа.

...