Остановите asyncio.run () от игнорирования остатка моего кода - PullRequest
0 голосов
/ 08 июня 2019

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

Я пробовал некоторые подходы к элементарному многопоточному и многопоточному пулам, но я нашел, что это наиболее успешный изЯ попытался:

# There's some code up here (A), and it runs synchronously and fine.

# Here's the asynchronous code (B).
pauseAsynchronousFunction = False

async def asynchronousFunction():
    global pauseAsynchronousFunction
    # Do stuff before hitting the while loop.
    while True:
        if pauseAsynchronousFunction == False:
            # Do some stuff.
        else:
            # Do some other stuff.

asyncio.run(pauseAsynchronousFunction())

# More synchronous code is down here (C), which it never reaches.

Я могу сказать, что это не работает, как я ожидаю, потому что другая функция ниже (в C) вызывает ту же глобальную переменную pauseAsynchronousFunction и переключает ее с False на True, а затем снова вернитесь к False после завершения работы.Это переключение никогда не происходит.

Я предполагаю, что проблема связана либо с while True, но я не понимаю, почему, если он асинхронный, или что он связан с отсутствиемawait заявление.Что еще я мог упустить?

ОБНОВЛЕНИЕ:

Я выполнил несколько попыток отладки с некоторой помощью pypypy и получил это.


pauseAsynchronousFunction = False

async def fun2():
    global pauseAsynchronousFunction
    while True:
        if pauseAsynchronousFunction == False:
            #do stuff
        else:
            #do other stuff

async def fun1():
    global pauseAsynchronousFunction
    pauseAsynchronousFunction = True
    #do stuff here that you wanted to do after the `asyncio.run` above
    pauseAsynchronousFunction = False
    return stuff

async def main():
    await asyncio.gather(
        fun1(),
        fun2(),
    )

asyncio.run(main)

Проблема заключается в следующем: pauseAsynchronousFunction переключается на True, но не переключается обратно на False в конце fun(1).

1 Ответ

1 голос
/ 08 июня 2019

asyncio.run будет блокироваться до тех пор, пока все асинхронные функции не будут возвращены.Таким образом, код, который вы имеете после asyncio.run(), должен быть преобразован в асинхронную функцию, то есть

import asyncio

async def fun2():
    global pauseAsynchronousFunction
    while True:
        if pauseAsynchronousFunction == False:
            print('not paused')
        else:
            print('paused')
        await asyncio.sleep(1)

async def fun1():
    global pauseAsynchronousFunction
    pauseAsynchronousFunction = True
    print('im pausing')
    await asyncio.sleep(5)
    print('im unpausing')
    pauseAsynchronousFunction = False
    return 0

async def main():
    await asyncio.gather(
        fun1(),
        fun2(),
    )

await main()

Вот альтернативный ответ с использованием потоков и событий:

import threading
import time

should_pause = threading.Event()

def fun2():
    while True:
        if should_pause.is_set():
            print('paused')
        else:
            print('not paused')
        time.sleep(1)


t = threading.Thread(target=fun2)
t.start()
should_pause.set()
print('waiting')
time.sleep(5)
print('finished-waiting')
should_pause.clear()
...