Коррутины в Lua: как писать пошаговый код без многопоточности

Разбираем коррутины в Lua — лёгкий способ приостанавливать и возобновлять функции. Идеально для игр, сетевых задач и асинхронного кода.

РазработкаLua

6 мин

Когда речь заходит о параллельности, большинство программистов сразу вспоминают многопоточность или асинхронность. Но у Lua есть свой уникальный инструмент — коррутины. Они позволяют писать код так, словно у вас есть несколько потоков, при этом оставаясь внутри одного потока выполнения.

Коррутины — это лёгкие "потоки", которые можно приостанавливать и возобновлять вручную.

В отличие от обычных функций, которые выполняются от начала до конца, корутина может:

  • остановиться в середине выполнения,

  • вернуть управление вызывающему коду,

  • а потом продолжить работу с того же места.

Это похоже на паузу в игре 🎮: вы сохранили состояние, а потом спокойно продолжили с того же момента.

Пример корутины в Lua

function worker()
    for i = 1, 3 do
        print("Шаг " .. i)
        coroutine.yield() -- приостанавливаемся
    end
end

co = coroutine.create(worker)

coroutine.resume(co) --> Шаг 1
coroutine.resume(co) --> Шаг 2
coroutine.resume(co) --> Шаг 3

Разбор:

  • coroutine.create — создаёт корутину.

  • coroutine.resume — запускает или продолжает её.

  • coroutine.yield — ставит выполнение на паузу.

Чем коррутины отличаются от потоков?

Потоки (Threads)

Коррутины (Coroutines)

Управляются ОС

Управляются самим Lua

Могут выполняться параллельно

Выполняются только один за другим

Сложные для отладки

Простые и предсказуемые

Требуют защиты данных (mutex, lock)

Безопасны, так как нет реального параллелизма

Где коррутины полезны?

  • Игры и анимации — пошаговые сценарии без вложенных if и таймеров.

  • Асинхронные задачи — сетевые запросы, обработка событий.

  • Скриптовые сценарии — простое описание поведения NPC или ботов.

Маленький пример для игры

function npc()
    print("NPC: Я иду...")
    coroutine.yield()
    print("NPC: Я остановился...")
    coroutine.yield()
    print("NPC: Я снова иду!")
end

co = coroutine.create(npc)
coroutine.resume(co) -- NPC: Я иду...
coroutine.resume(co) -- NPC: Я остановился...
coroutine.resume(co) -- NPC: Я снова иду!

Вместо сложной логики — простой сценарий, как будто пишете мини-театр для объектов.

Итог

Коррутины в Lua — это не многопоточность, но лёгкий способ имитации параллельного выполнения. Они идеально подходят для игр, сетевых приложений и сценариев, где важен контроль за порядком действий.

Если вы учите Lua — обязательно поиграйтесь с корутинами. Это может сильно упростить вашу архитектуру. В кодике интересные курсы с заданиями по Lua.

А ещё у нас есть активный telegram-канал, где мы обсуждаем крутые идеи, делимся опытом и вместе разбираем задачи — учиться становится не только полезно, но и весело.

Комментарии