admin管理员组

文章数量:1394526

I learn python asyncio and now struggling with Conditions. I wrote a simple code:

import asyncio


async def monitor(condition: asyncio.Condition):
    current_task_name = asyncio.current_task().get_name()
    print(f'Current task {current_task_name} started')
    async with condition:
        await condition.wait()
        print(f'Condition lock released for task {current_task_name}, start doing smthg')
        await asyncio.sleep(2)
        print(f'Current task {current_task_name} finished')


async def setter(condition: asyncio.Condition):
    print(f'Setter starts')
    async with condition:
        await asyncio.sleep(1)
        condition.notify_all()  # Пробуждаем все задачи
        print('Setter finished')
    print('Setter unlocked')


async def main():
    cond = asyncio.Condition()
    async with asyncio.TaskGroup() as tg:
        tg.create_task(setter(cond))
        [tg.create_task(monitor(cond)) for _ in range(3)]
        # tg.create_task(setter(cond))
        

asyncio.run(main())

But the code catches a DeadLock after Setter unlocked message. I cant realise why. But if I swap task creation order in main and create monitor tasks prior to creation setter task- all good.

please, I am a very new in asyncio, so please, in simple words...

I learn python asyncio and now struggling with Conditions. I wrote a simple code:

import asyncio


async def monitor(condition: asyncio.Condition):
    current_task_name = asyncio.current_task().get_name()
    print(f'Current task {current_task_name} started')
    async with condition:
        await condition.wait()
        print(f'Condition lock released for task {current_task_name}, start doing smthg')
        await asyncio.sleep(2)
        print(f'Current task {current_task_name} finished')


async def setter(condition: asyncio.Condition):
    print(f'Setter starts')
    async with condition:
        await asyncio.sleep(1)
        condition.notify_all()  # Пробуждаем все задачи
        print('Setter finished')
    print('Setter unlocked')


async def main():
    cond = asyncio.Condition()
    async with asyncio.TaskGroup() as tg:
        tg.create_task(setter(cond))
        [tg.create_task(monitor(cond)) for _ in range(3)]
        # tg.create_task(setter(cond))
        

asyncio.run(main())

But the code catches a DeadLock after Setter unlocked message. I cant realise why. But if I swap task creation order in main and create monitor tasks prior to creation setter task- all good.

please, I am a very new in asyncio, so please, in simple words...

Share Improve this question asked Mar 27 at 11:09 IzaeDAIzaeDA 3856 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 3

In your original code, the setter task is started before the monitor tasks. When setter calls notify_all(), no monitor tasks are yet waiting so no tasks are notified. Later, the monitors reach condition.wait() but remain stuck because no further notifications are sent.

When you reverse the order, starting monitor tasks first, they begin waiting on the condition before the setter notifies. As a result, they are properly awakened and the deadlock is avoided.

To fix the issue, ensure that all tasks that should wait on the condition are created and running before calling notify_all().

本文标签: Python Asyncio Condition Why DeadLock appearsStack Overflow