mock_sobes
← asyncio — Практика (race, блокировки, async I/O)
middle correct_vs_wrong #17
Два варианта инкремента общего счётчика из нескольких корутин. Есть ли в asyncio race condition вообще? Какой код правильный?
Вариант 1
counter = 0

async def increment():
    global counter
    tmp = counter            # ← await может прервать здесь
    await asyncio.sleep(0)   # имитация любой await-точки
    counter = tmp + 1

async def main():
    await asyncio.gather(*(increment() for _ in range(1000)))
    # counter может быть < 1000
Вариант 2
counter = 0
lock = asyncio.Lock()

async def increment():
    global counter
    async with lock:
        tmp = counter
        await asyncio.sleep(0)
        counter = tmp + 1

async def main():
    await asyncio.gather(*(increment() for _ in range(1000)))
    # counter == 1000
Чтобы решить вопрос и сохранить попытку — войди.