본문 바로가기

[ C/ C++ 프로그래밍 ]/[ 루아 ]

[ 루아 ] 코루틴

코루틴은 흔히 다른 언어에서 말하는 스레드(thread)와 비슷한 개념이다.
코루틴은  스레드와 같이 자기 자신만의 지역변수와 스택 그리고 실행 순서를 가지고 독립적으로 실행된다.
스레드와 코루틴은 큰 차이는 코루틴의 실행 모델은 비선점(non - preemptive ) 형이라는 것이다.
즉 한번 루틴이 실행되면 그 실행이 끝날 때까지 외부의 조작에 의해 실행이 중단되지 않는다는 뜻이다.
쉽게 한번 CPU Time 을 정유하면 실행이 끝나기 전에는 다른 루틴은 CPU Time을 쓸 수 없다는 말이다.
코루틴을 사용하기 위해서는 제공하는 라이브리 함수를 사용해야 한다.

ㅇ 코루틴의 기본
 
- coroutine.create
 코루틴을 생성하기 위해서 coroutine.create(f)라는 함수를 호출해야함, 매개변수 f는 루아 함수여야 한다.anonymous fuction이라도 상관없음

소스 다운 :
  





위의 결과를 보면  cr1,cr이라는 코루틴을 생성하고 그 값을 확인해 보기 위해 print해 보면 'thread'라는 결과가 나오는 것을 볼수 있다.
create는 말 그래도 생성만 할 뿐이다. 그 루틴을 실해 주지 않는 다는 것이다.


ㅇ coroutine.resume
resume은  생성한 것을 실행하게 해주는 함수이다.

- 기본형태
 coroutine.resume ( co [, arg1, ... ] )

※ co : 시작하고자하는 코루틴,   arg1, ... : 코루틴의 함수에 전달할 매개변수 값

실행 대상은 코루틴이 에러 없이 정상적으로 실행이 완료되었다면 'true'와 함께 코루틴이 넘겨준 값을 리턴한다.
에러가 발생했다면 'false'와 함께 에러 메시지를 리턴한다.

타 언어와 비교 하자면 ResumeThread 혹은 Thread.start of Thread.resume 정도 되겠다

소스 다운 :
  




- coroutine.yield
 현재 실행 중인 코륀의 실행을 잠시 중지 시킨다.  그리고 resume로 다시 실행 시킬 수 있다.  
 (나는 왜 실행의 명령어가 resume로 되어있냐고 생각했는데 이 기능을 보고 아 그렇구나 하고 생각했다. 짧은 내 생각ㅠ)
또하 해당 코루틴은 suspend 상태가 되고, 실행 권한을 호출자에게 넘긴다.

ex) coroutine.yield(returnValue)    // 여기서 returnValue는 resume의 리턴값으로 더해져서 리턴된다.

소스 다운 :
  






- coroutine.status
 코루틴의 현재 상태를 리턴한다.



소스 다운 :
  




생성후 시작하지 않은 루틴은 suspened
정상적인 수행 후에는 dead
yield 함수를 사용해 실행을 중지 시켰을때는 suspended

- coroutine.wrap
 create와 같은 기능을 하는 함수, 새로운 코루틴의 생성, 두 함수의 차이는 리턴값 , create는 코루틴 자체를 리턴, wrap는 함수를 리턴 그래서 시작하는 방법이 다름

소스 다운 :
  




위의 실행 겨로가에서 알 수 있는 다른 한가지 차이는 resume시에 . 그러니까 함수를 호출했을 경우 리턴되는 값이 reume은 첫번째 리턴값이  Boolean이 었는데 비해,
wrap으로 생성된 코루틴은 그 값이 없다는 것이다. 나머지 뒤에 매개변수들이 리턴되는 것은 같다.


ㅇ 코루틴 사용 예
여러가지 사용 용도중에 하나가 iterator(이테레이터) 이다.
iterator는  연속적으로 저장된 값을 읽어가는 (traverse) 역할을 한다.
따라서 이러한 iterator를 코루틴을 통해 구현하면 매우 단정한 논리 흐름을 만들 수 있다. 코드의논리가 깔끔해진다는 것이다.

소스 다운 :





wrap 대신 create 함수를 이용해서도 구현이 가능하다

출처 및 참고 : 예제로 배우는 프로그래밍 루아