마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

코루틴(coroutine)의 suspend 함수 질문이요!

0 추천
안녕하세요. Coroutine에 대해 공부하고 있는 학생입니다.

학습 도중, suspend function에 대해 의문이 생겨 몇 가지 실험을 해보았습니다.

 

 

fun A: 시간이 오래 걸리는 함수A

fun B: 마찬가지로 시간이 오래 걸리는 함수B

1.

CoroutineScope(Dispatchers.IO).launch{

    fun A()

}

CoroutineScope(Dispatchers.IO).launch{

    fun B()

}

이것과

 

2.

CoroutineScope(Dispatchers.IO).launch{

    suspend fun A()

}

CoroutineScope(Dispatchers.IO).launch{

    suspend fun B()

}

 

이 두 방식의 차이가 궁금합니다.

 

학습 중 제가 이해한 것은, suspend 함수가 코루틴 Scope 내에서 일반 함수와는 달리

도중에 suspend를 통하여 다른 이에게 일을 넘겨줄 수 있다(프로세서를 넘겨준다 해야할까요?)고 이해하였습니다.

따라서 위 1, 2번 실험을 할 경우

2번은 fun A와 fun B가 번갈아가면서 실행되는 반면

1번은 fun A가 끝날때까지 fun B가 실행이 안될 줄 알았습니다.

 

하지만 결과는 1번, 2번 둘 다 번갈아가면서 실행이 되었습니다.

(물론 2번이 더 자주 서로 번갈아 실행되더군요)

 

물론 둘 다 별도의 코루틴 Scope를 지정하였기에 동시 실행이 보장된 것이다라고 이해는 되는데...

그럼 suspend function을 쓰고 안쓰고의 차이는 어디서 느낄 수 있는걸까요?
베어헌터 (270 포인트) 님이 2020년 11월 28일 질문

1개의 답변

0 추천
 
채택된 답변
제가 아는 바로는 suspend 는 코루틴 키워드이기 때문에 컴파일하게 되면 코틀린 컴파일러가 해당 함수를 콜백형태로 전환해 줍니다. 코루틴의 콜백은 Continuation이라는 클래스로 불립니다. 예를 들어 다음의 함수,
suspend fun fun1(arg: Int) {

}

컴파일이 되면

fun fun1(arg: Int, cont: Continuation) {
    when (cont.flag) {
      1 -> {}
      2 -> {}
   ....}

}
와 같은 형태로 변환이 됩니다. Continuation은 해당 함수가 실행될 상태를 보관하게 되고 여기에 플래그가 달리는데 이 플래그를 보고 fun1을 재귀호출해서 함수가 실행되게 됩니다. 즉, 약간 fancy한 콜백이라고 해야 될까요?
암튼 코루틴의 Continuation 콜백을 코틀린 컴파일러의 도움으로 콜백으로 보이지 않게 내부적으로 감추어 줍니다. 유투브의 KotlinConf를 찾아보시면 코루틴 메인개발자가 코루틴의 내부적으로 어떻게 동작하는지 좀 더 명료하게 알려줍니다. 설명은 간단하지만 내부는 엄청나게 복잡한 concurrency 라이브러리입니다. 그리고 예외처리, 실행취소 등과 관련해서는 눈으로 보이는 것과는 다르게 어려운 부분이 있습니다.

안드로이드 스튜디오의 Tools -> Kotlin 메뉴에 가시면 코틀린의 디컴파일된 코드를 확인하실 수 있습니다. 코틀린이 어떻게 자바코드로 바뀌는지 확인해 보시면 좀 더 감이 오실 거라고 생각합니다.
spark (228,990 포인트) 님이 2020년 11월 28일 답변
베어헌터님이 2020년 11월 28일 채택됨
suspend 함수는 코틀린 컴파일러가 언제든 중단시킬 수 있도록 도움을 주는 정도로 이해가 됐습니다! 말씀주신 키워드로 검색해보니 when 방식의 state machine을 둠으로써 상태저장이 훨씬 용이하게 되더라구요. fancy한 콜백이란 말이 많이 와닿네요. 감사합니다!
...