最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Python Asyncio Condition: Why DeadLock appears? - Stack Overflow

programmeradmin8浏览0评论

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().

发布评论

评论列表(0)

  1. 暂无评论