Вы можете достичь того, что вы хотите с замком. Проблема с вашим кодом заключается в том, что вы никогда не получаете блокировку в start_tic_tock
, поэтому у вас нет возможности «приостановить» эту сопрограмму на основе блокировки, полученной в other_task
.
. чтобы ваш start_tic_tock
метод получил блокировку следующим образом:
async def start_tic_tock(print_val):
while True:
async with lock:
task_tic_tock(print_val)
await asyncio.sleep(1)
При этом Событие может лучше соответствовать тому, что вы хотите. События явно предназначены для уведомления задач, когда условие достигнуто. Полный код ниже, используя событие. Обратите внимание, что когда вы создаете Event
или Lock
глобально, как вы делаете в приведенном выше коде, вы можете создавать новое событие l oop. asyncio.run
всегда создает новый l oop, что означает, что вы можете запустить два цикла, что может привести к исключениям. В приведенном ниже я явно создал al oop, чтобы избежать этих ошибок, вам нужно немного изменить рефакторинг, чтобы снова использовать asyncio.run
.
import asyncio
loop = asyncio.new_event_loop()
event = asyncio.Event(loop=loop)
async def start_tic_tock(print_val):
while True:
await event.wait()
task_tic_tock(print_val)
await asyncio.sleep(1)
async def other_task():
count = 0
while True:
count = count + 1
if count % 3 == 0:
event.clear()
task_tic_tock(False)
new_count = 5
while new_count > 0:
print("In new count")
new_count = new_count - 1
await asyncio.sleep(1)
event.set()
await asyncio.sleep(1)
print("Other task running")
await asyncio.sleep(1)
async def main():
print_val = asyncio.create_task(start_tic_tock(True))
await asyncio.gather(other_task(), print_val)
loop.run_until_complete(main())
Приведенные выше отпечатки:
Print val is now false
In new count
In new count
In new count
In new count
In new count
tic-tock
tic-tock
tic-tock