코루틴 조작 라이브러리

코루틴 조작 라이브러리 (Coroutine Manipulation)

coroutine 라이브러리는 루아의 코루틴을 만들고 제어하는 함수를 제공해요. 코루틴의 개념은 "[코루틴 (Coroutines)]" 절에서 자세히 다뤄요. 여기서는 각 함수의 레퍼런스를 설명해요.

coroutine.close

coroutine.close (co)

코루틴 co를 닫아요. co"suspended" 상태면, 아직 실행하지 않은 부분을 실행해 실행을 완료시키고 to-be-closed 변수를 정리한 뒤 "dead" 상태로 만들어요. co가 이미 "dead" 상태면 아무것도 하지 않아요. 닫기에 실패하면(예: 실행 중 오류) 그 오류를 반환하거나, 유효하지 않으면 오류를 발생시켜요. 성공 시 true를 반환해요.

coroutine.create

coroutine.create (f)

본문(body)이 함수 f인 새 코루틴을 만들어요. 새 코루틴은 "suspended" 상태예요. coroutine.resume으로 재개하기 전까지는 아무것도 실행하지 않아요.

local co = coroutine.create(function() print("hello") end)
print(coroutine.status(co))  --> suspended
coroutine.resume(co)         --> hello

coroutine.isyieldable

coroutine.isyieldable ([co])

코루틴 co(생략 시 현재 실행 중인 코루틴)가 현재 양보할 수 있는지 여부를 boolean으로 반환해요.

  • 메인 스레드(독립 실행 최상위)는 양보할 수 없어요 → false.
  • C 함수 안에서 양보 가능한지에 따라 다름. 양보하지 못하는 C 함수 안이면 false.

coroutine.resume

coroutine.resume (co [, val1, ...])

코루틴 co를 재개(시작 또는 이어 실행)해요.

  • 코루틴이 "suspended"면 처음 실행을 시작하고, val1, ...은 본문 함수의 인자가 돼요.
  • 코루틴이 yield로 중단된 상태면 그 양보 지점에서 이어서 실행하고, val1, ...yield의 반환값이 돼요.
  • 성공하면 true와, 코루틴이 반환하거나 양보한 모든 값들을 반환해요.
  • 실패하면 false와 오류 객체를 반환해요. 오류로 실패하면 코루틴은 "dead" 상태가 돼요.

coroutine.running

coroutine.running ()

현재 실행 중인 코루틴을 반환해요. 메인 스레드에서는 첫 번째 반환값이 nil이고, 코루틴에서면 첫 번째 반환값이 현재 코루틴이에요. 두 번째 반환값은 메인 스레드인지 여부(boolean)를 나타내요.

local co = coroutine.create(function()
  local c, ismain = coroutine.running()
  print(c == co, ismain)   --> true false
end)
coroutine.resume(co)

coroutine.status

coroutine.status (co)

코루틴 co의 상태 문자열을 반환해요. 가능한 값:

  • "running" — 코루틴이 현재 실행 중 (자기 자신을 조회할 때).
  • "suspended" — 코루틴이 중단됨 (create 직후 또는 yield 후).
  • "normal" — 코루틴이 활성이지만 실행 중이 아님 (다른 코루틴이 yield로 제어받음).
  • "dead" — 코루틴이 실행을 끝냈거나 오류로 종료됨.

coroutine.wrap

coroutine.wrap (f)

본문이 f인 코루틴을 만들고, 그 코루틴을 재개하는 클로저(함수) 를 반환해요. 반환된 함수를 호출할 때마다 인자로 코루틴을 재개해요.

  • 차이점은 resumetrue/오류 플래그를 제거하고, 정상 결과만 반환한다는 점이에요.
  • 오류가 발생하면 그 오류를 그대로 던져요 (보호되지 않음).
  • 코루틴이 이미 끝난 후 호출하면 "cannot resume dead coroutine" 오류를 내요.

이 클로저는 생성기(generator)나 반복자로 쓰기 편리해요.

local gen = coroutine.wrap(function()
  coroutine.yield(1)
  coroutine.yield(2)
  return 3
end)
print(gen())  --> 1
print(gen())  --> 2
print(gen())  --> 3

coroutine.yield

coroutine.yield (...)

현재 실행 중인 코루틴의 실행을 중단하고, ... 값을 resume을 호출한 쪽에 돌려줘요. 코루틴이 다시 resume되면, yield 호출은 그 resume이 전달한 인자들을 반환해요.

메인 스레드나 양보하지 못하는 함수 안에서 yield를 호출하면 오류가 발생해요.

코루틴 활용 예시

인자 전달과 반환을 둘 다 보여주는 예시예요.

local co = coroutine.create(function(a)
  print("a =", a)
  local b = coroutine.yield(a + 1)
  print("b =", b)
  return a + b
end)

print(coroutine.resume(co, 10))   --> a = 10 / true 11
print(coroutine.resume(co, 20))   --> b = 20 / true 30

참고

coroutine 라이브러리의 함수는 thread 타입을 직접 조작해요. 코루틴의 스케줄링은 완전히 협력적이므로, 실행의 전환은 명시적인 yield/resume으로만 일어나요.

출처: 코루틴 조작 (Coroutine Manipulation)

본문

재개와 값 전달

resumeyield는 값 전달의 두 방향을 담당해요. 재개 시 전달한 인자는 이전 yield의 반환값이 되고, yield 시 전달한 값은 resume의 반환값이 돼요. 이 양방향 통신이 코루틴 기반 협력적 프로그래밍의 핵심이에요.

상태 전이

코루틴은 createsuspended에서 시작해, resume으로 running이 되고, yieldsuspended(혹은 다른 코루틴을 재개한 경우 normal)가 되며, 본문을 마치거나 오류로 dead가 돼요.

더 알아보기