-
[Coroutine] 코루틴 학습 - 2 (Under the hood)Java/Kotlin 2022. 4. 23. 16:58반응형
Under the hood Coroutine
- 일시중단 함수는 함수의 실행과 실행 후에도 실행 가능한 상태 머신과 같다.
- 상태를 식별하는 번호와 로컬 데이터는 continuation 객체에 저장한다.
- 한 함수의 Contunuation 다른 함수의 Continuation을 데코레이트 시키고, 결과적으로 모든 continuation은 다시 시작될 때 사용하는 콜스택을 나타낸다.
Continuation-passing style
- 일시중단 함수를 구현 시, Continuation은 함수에서 함수로 마지막 argument로 전달된다.
suspend fun getUser(): User? suspend fun setUesr(uesr: User) suspend fun checkAvailability(flight: Flight): Boolean fun getUser(continuation: Continuation<*>): Any? fun setUser(user: User, continuation: Continuation<*>): Any fun checkAvailability(flight: Flight, continuation: Continuation<*>): Any
- 일시중단 함수가 내부적으로 동작할 때, continuation이 argument로 전달되는 형태로 선언되는 것을 확인할 수 있는데, Unit과 Boolean은 Any로, User? 는 Any?로 바뀐 것을 확인할 수 있다.
- 이는 일시중단 함수가 일시중단 되었을 때, 선언된 타입을 반환하지 않을 수 있기 때문이다.
- 이러한 경우, COROUTINE_SUSPENDED 라는 특수한 마커 타입을 반환한다.
- 위의 예시에서는 getUser() 함수가 User? 또는 COROUTINE_SUSPENDED를 반환한다.
- 일시중단 함수는 두 가지 시작점에서 시작되는데, 최초로 함수가 호출되었을 경우와 일시중단 후에 재개되었을 때이다.
- 두 상태를 식별하기 위해서 label이라는 필드를 사용한다.
- 처음 시작되었을 때는 0이고, 일시중단 지점 앞에서 다음 상태로 변경된다. 그리고 다시 재개될 때는 일시중단 지점 앞에서 실행된다.
만약 상태 값(local 변수)을 가지고 있는 함수가 일시 중단 되었을 경우에는?
- 상태를 가지고 있는 일시중단 함수가 일시중단 되었다가 재개 되었을 때는 여전히 해당 상태를 가지고 연산을 처리할 수 있어야한다.
- 이를 위해서 일시중단 함수는 상태값을 복원하기 위해 Continuation에 상태를 저장한다.
값을 가지는 함수가 다시 재개되었을 때의 동작
suspend fun printUser(token: String) { println("Before") val userId = getUserId(token) // suspending println("Got userId: $userId") val userName = getUserName(userId) // suspending println(User(userId, userName)) println("After") }
- 위 일시중단 함수인 printUser() 안에서 일시중단 함수인 getUserId(), getUserName()가 호출되고 있다.
- 함수가 value로 재개되었다면, 그 결과로 Result.Success(value)를 반환한다.
- 만약 예외로 재개되었다면, 그 결과로 Result.Failure(exception)을 반환한다.
일시중단 함수에서의 콜 스택
- 일시중단 함수는 일시중단되면 쓰레드를 반환하고, 그 결과로 콜스택을 클리어한다.
- 콜스택의 기능을 제공하기 위해 각 Continuation들은 중단되었을 때의 상태(지역변수와 파라미터 등)와 호출된 continuation 참조들을 저장해둔다. 즉, 하나의 continuation이 다른 continuation을 참조하고, 다른 continuation이 또 다른 continuation을 참조하는 것이다.
- 일반적인 콜스택과 일시중단 함수가 제공하는 콜스택 도식도는 아래와 같다.
참고자료
https://www.amazon.com/Kotlin-Coroutines-Deep-Marcin-Moskala/dp/8396395837
반응형'Java > Kotlin' 카테고리의 다른 글
[Coroutine] 코루틴 학습 - 6 (Job and children awaiting) (0) 2022.05.01 [Coroutine] 코루틴 학습 - 5 (Coroutine context) (0) 2022.04.28 [Coroutine] 코루틴 학습 - 4 (Structured Concurrency) (0) 2022.04.27 [Coroutine] 코루틴 학습 - 3 (Coroutine Builders) (0) 2022.04.27 [Coroutine] 코루틴 학습 - 1 (Coroutine?) (0) 2022.04.16