[Unity] 코루틴은 비동기일까 동기일까?
코루틴을 누군가에게 설명하라고 하면 비동기적인 기능을 만들 때 주로 사용한다고
말할 것이다. 하지만 코루틴은 사실 비동기인 것 처럼 보이는 것이지 동기적으로 진행된다고
알고있다. 그래서 이 애매한 지식을 확실하게 파악하기 위하여 코루틴의 대한 개념을 정리하고자한다.
1. 코루틴이 뭐야?
코루틴이란 순차적인 방식으로 비동기식 코드를 작성할 수 있도록 하는 함수다.
코루틴을 사용할 때는 IEnumerator형으로 메서드를 선언하고
yield return문을 사용하여 비동기적 기능을 제작할 수 있다.
주로 특정 기간동안 실행을 중지할 수 있는 yield return new WaitForSeconds를 사용하거나
한 프레임동안 실행을 중지할 수 있는 yield return null을 사용한다.
이렇게 메서드를 만들었다면 코루틴의 시작은 StartCoroutine으로 실행할 수 있고
StopCoroutine이나 StopAllCoroutine으로 코루틴을 종료할 수 있다.
이러한 방법으로 작성한 위 코드를 실행해보면
처음엔 바로 실행되고
다음으로 WaitForSeconds(3f)로 인하여 3초 후에 실행되고
다음으로 WaitForSeconds(4f)로 인하여 총 7초 후에 실행되는 것을 확인할 수 있다.
2. 그래서 코루틴은 비동기야?
코루틴은 비동기 프로그래밍을 구현하는데 주로 사용되지만, 실제로는 비동기가 아닌 동기적으로 진행된다.
여기서 말하는 코루틴의 비동기는 코루틴을 일시 중단하고 나중에 재개할 수 있는 능력을 말하며
코루틴 자체는 유니티의 단일 스레드를 이용한 동기적인 과정으로 진행된다.
코루틴을 작성할 때 yield return문을 무조건 사용해야한다.
이 과정은 코루틴이 특정 지점에서(yield return 사용 지점) 메인 스레드에 제어를 양보하며
코루틴 갱신 사이에 다른 작업이 수행될 수 있도록 하는 것이다.
이는 코루틴이 유니티의 프레임 기반 실행 모델을 활용한 것으로 새로운 스레드를 생성하지 않고
메인 스레드 하나를 제어하며 순차적으로 실행하되, 비동기적인 동작처럼 보이게 하는 것이다.
그래서 실제로 코루틴은 Unity의 기본 스레드에 의존하기 때문에 병렬 처리나 다중 스레딩을
제공하지 않는다. 따라서 복잡한 병렬작업을 해야할 경우 코루틴을 사용하면 안되고
async/await 같은 실제 비동기 기술을 사용해야한다.
결론
코루틴은 비동기인 것처럼 기능을 해주는 것이지 사실은 비동기가 아니다.
3. IEnumerator는 무슨 기능을 하는거야?
코루틴의 메서드를 보면 IEnumerator를 반환하면서 안에 기능이 담겨있는 것을 확인할 수 있다.
IEnumerator가 무엇이길래 반환값으로 사용하며 메서드를 작성하는 것일까?
그 이유는 앞서 말한 코루틴의 제어권한을 넘기는 특징 때문이다.
IEnumerator는 열거자를 말하며 열거자는 yield 반환문을 포함해야한다.
여기서 yield는 앞서 말한 코루틴의 특징인 일시적으로 제어권한을 넘겨주는 역할을 한다.
열거자는 일시적으로 권한을 넘겨주기 때문에 권한을 넘겨줘도 자신이 실행하고 있는 상태를
기억하고 있으며 이를 통해 return문이 있더라도 메서드가 종료되는 것이 아닌
제어권한을 넘긴 부분으로 돌아와 다음 코드를 실행하게 된다.
결론
IEnumerator는 열거자이며 yield를 통해 제어권한을 잠시 넘겨줄 수 있는 기능이다.