Как запустить цикл while параллельно с программой, для его принудительной остановки?

Как можно остановить цикл while "извне" на моём примере? Я вызываю функцию с циклом после выполнения команды старта в телеграм боте. Затем, написав какое либо сообщение в бот, мне нужно, чтобы цикл while станавливался, но этого не происходит, т.к. программа занята циклом:

global enabled
enabled = False
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    # при вызове команды старт в боте запускаю цикл while в perpetual
    global enabled
    enabled = True
    perpetual()

def perpetual():
    global enabled

    delay = 1.0
    start_time = dt.datetime.now().timestamp()

    while enabled: # "пока enabled, то раз в секунду что-то делай"
        print("...")
        time.sleep(delay - ((time.monotonic() - start_time) % delay)) # sleep 1 second


async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    # функция не выполняется, потому что функция perpetual не завершена
    global enabled
    enabled = False

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


Ответы (1 шт):

Автор решения: Danil

Решил проблему, используя asyncio.create_task()

async def perpetual():
    global enabled
    while enabled:
        await asyncio.sleep(1.0)
        print("precessing")

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    global enabled
    enabled = True

    user = update.effective_user
    task = asyncio.create_task(perpetual())

async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    global enabled
    enabled = False

    print("perpetual stopped")
→ Ссылка