В FastAPI-обработчике одновременно запускают 20 корутин, каждая читает и меняет общий словарь лимитов. Объясни, почему однопоточный цикл событий не гарантирует корректность этой составной операции и где именно возникнет гонка.

Гонка возникает, если между чтением лимита и записью нового значения есть await: другая корутина может использовать тот же старый лимит. Один поток не делает такую операцию атомарной.

Короткий ответ

Что ответить на собеседовании

Гонка возникает, если между чтением лимита и записью нового значения есть await: другая корутина может использовать тот же старый лимит. Один поток не делает такую операцию атомарной.

Подробный разбор

Ответ с пояснениями

Гонка возникает, если между чтением лимита и записью нового значения есть await: другая корутина может использовать тот же старый лимит. Один поток не делает такую операцию атомарной.

Например, обе корутины читают остаток 1, затем ожидают внешнюю проверку и обе разрешают запрос, записывая 0. В одном event loop непрерывный участок без передачи управления не прерывается другой обычной coroutine-задачей, поэтому конкретное место await принципиально. Используйте общий asyncio.Lock вокруг локального read-modify-write или атомарную операцию хранилища. Локальный lock не защищает от других worker-процессов и серверов. Лучше резервировать квоту атомарно, а внешний вызов выполнять вне длительной блокировки.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее