수색…


통사론

  • coroutine.create (함수)는 함수를 포함하는 코 루틴 (type (coroutine) == 'thread')을 반환합니다.

  • coroutine.resume (co, ...)는 coroutine을 다시 시작하거나 시작합니다. 다시 시작하기 위해 주어진 추가 인수는 이전에 coroutine을 일시 중지 한 coroutine.yield ()에서 반환됩니다. 코 루틴이 시작되지 않은 경우 추가 인수가 함수의 인수가됩니다.

  • coroutine.yield (...)는 현재 실행중인 동시 루틴을 생성합니다. 실행은 coroutine을 시작한 coroutine.resume () 호출 후 백업을 선택합니다. yield에 주어진 모든 인수는 코 루틴을 시작한 해당 coroutine.resume ()에서 반환됩니다.

  • coroutine.status (co)는 다음과 같은 coroutine의 상태를 반환합니다.

    • "죽은": coroutine의 기능이 끝났으며 coroutine을 더 이상 다시 시작할 수 없습니다.
    • "실행 중": 코 루틴이 재개되어 실행 중입니다.
    • "보통": 코 루틴이 다른 코 루틴을 재개했습니다.
    • "중단됨": 코 루틴이 양보되고 다시 시작되기를 기다리고 있음
  • coroutine.wrap (function)은 호출 될 때 coroutine.create (function)에 의해 생성 된 코 루틴을 다시 시작하는 함수를 반환합니다.

비고

코 루틴 시스템은 다른 언어로 존재하는 다중 쓰레드를 에뮬레이트하기 위해 루아에서 구현되었습니다. 그것은 다른 기능들 사이에서 매우 빠른 속도로 스위칭함으로써 작동하며, 따라서 인간 사용자는 그들이 동시에 실행된다고 생각합니다.

코 루틴 생성 및 사용

coroutine과 상호 작용하는 모든 함수는 coroutine 테이블에서 사용할 수 있습니다. coroutine.create 함수를 단일 인수와 함께 사용하여 새로운 동시 루틴을 만듭니다. 실행할 코드가있는 함수 :

thread1 = coroutine.create(function()
            print("honk")
        end)

print(thread1)
-->> thread: 6b028b8c

coroutine 객체는 새로운 coroutine을 나타내는 thread 유형의 값을 반환합니다. 새 동시 루틴이 만들어지면 초기 상태가 일시 중단됩니다.

print(coroutine.status(thread1))
-->> suspended

다시 시작 또는 코 루틴, 함수 coroutine.resume을 사용을 시작하려면, 주어진 첫 번째 인수는 스레드 객체는 다음과 같습니다

coroutine.resume(thread1)
-->> honk

이제 코 루틴은 코드를 실행하고 종료하여 상태를 죽은 상태로 변경합니다. 다시 시작할 수 없습니다.

print(coroutine.status(thread1))
-->> dead

코 루틴coroutine.yield 함수를 사용하여 실행을 일시 중지하고 나중에 다시 시작할 수 있습니다.

thread2 = coroutine.create(function()
        for n = 1, 5 do
            print("honk "..n)
            coroutine.yield()
        end
    end)

보시다시피 coroutine.yield () 는 for 루프 안에 있으며, 이제 coroutine을 다시 시작할 때 coroutine.yield에 도달 할 때까지 코드를 실행합니다.

coroutine.resume(thread2)
-->> honk 1
coroutine.resume(thread2)
-->> honk 2

루프를 완료하면 스레드 상태가 죽어 다시 시작될 수 없습니다. 코 루틴은 또한 데이터 교환을 허용합니다.

thread3 = coroutine.create(function(complement)
    print("honk "..complement)
    coroutine.yield()
    print("honk again "..complement)
end)
coroutine.resume(thread3, "stackoverflow")
-->> honk stackoverflow

코 루틴이 추가 인수없이 다시 실행되면 보완 은 여전히 ​​첫 번째 이력서 (이 경우 "stackoverflow")의 인수입니다.

coroutine.resume(thread3)
-->> honk again stackoverflow

마지막으로 coroutine이 끝나면 함수에 의해 반환 된 값은 해당하는 resume으로 이동합니다.

thread4 = coroutine.create(function(a, b)
    local c = a+b
    coroutine.yield()
    return c
end)
coroutine.resume(thread4, 1, 2)
print(coroutine.resume(thread4))
-->> true, 3

코 루틴은 재귀 호출 내에서 호출 스레드로 값을 다시 전달하기 위해이 함수에 사용됩니다.

local function Combinations(l, r)
    local ll = #l
    r = r or ll
    local sel = {}
    local function rhelper(depth, last)
        depth = depth or 1
        last = last or 1
        if depth > r then
            coroutine.yield(sel)
        else
            for i = last, ll - (r - depth) do
                sel[depth] = l[i]
                rhelper(depth+1, i+1)
            end
        end
    end
    return coroutine.wrap(rhelper)
end

for v in Combinations({1, 2, 3}, 2) do
    print("{"..table.concat(v, ", ").."}")
end
--> {1, 2}
--> {1, 3}
--> {2, 3}

coroutines는 또한 lazy evaluation을 위해 사용될 수 있습니다.

-- slices a generator 'c' taking every 'step'th output from the generator
-- starting at the 'start'th output to the 'stop'th output
function slice(c, start, step, stop)
    local _
    return coroutine.wrap(function()
        for i = 1, start-1 do
            _ = c()
        end
        for i = start, stop do
            if (i - start) % step == 0 then
                coroutine.yield(c())
            else
                _ = c()
            end
        end
    end)
end


local alphabet = {}
for c = string.byte('a'), string.byte('z') do
    alphabet[#alphabet+1] = string.char(c)
end
-- only yields combinations 100 through 102
-- requires evaluating the first 100 combinations, but not the next 5311633
local s = slice(Combinations(alphabet, 10), 100, 1, 102)
for i in s do
    print(table.concat(i))
end
--> abcdefghpr
--> abcdefghps
--> abcdefghpt

코 루틴은 루아 에서의 프로그래밍에 설명 된대로 파이프 구조에 사용될 수 있습니다. PiL의 저자 인 Roberto Ierusalimschy는 코 루틴 (coroutines)을 사용하여 연속과 같은보다 진보 된 일반 흐름 제어 기법을 구현하는 방법 에 대한 논문 을 발표했습니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow