코루틴 조작 라이브러리
코루틴 조작 라이브러리 (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인 코루틴을 만들고, 그 코루틴을 재개하는 클로저(함수) 를 반환해요. 반환된 함수를 호출할 때마다 인자로 코루틴을 재개해요.
- 차이점은
resume의true/오류 플래그를 제거하고, 정상 결과만 반환한다는 점이에요. - 오류가 발생하면 그 오류를 그대로 던져요 (보호되지 않음).
- 코루틴이 이미 끝난 후 호출하면
"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으로만 일어나요.
본문
재개와 값 전달
resume과 yield는 값 전달의 두 방향을 담당해요. 재개 시 전달한 인자는 이전 yield의 반환값이 되고, yield 시 전달한 값은 resume의 반환값이 돼요. 이 양방향 통신이 코루틴 기반 협력적 프로그래밍의 핵심이에요.
상태 전이
코루틴은 create→suspended에서 시작해, resume으로 running이 되고, yield로 suspended(혹은 다른 코루틴을 재개한 경우 normal)가 되며, 본문을 마치거나 오류로 dead가 돼요.