ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Coroutine] 코루틴 학습 - 4 (Structured Concurrency)
    Java/Kotlin 2022. 4. 27. 09:37
    반응형

    Structured Concurrency

    • 지난 포스트에서 살펴봤던 launch builder에서 GlobalScope는 코루틴이 완료되지 않아도 기다리지 않고 프로세스가 종료되었다. (코루틴은 쓰레드를 블로킹하지 않기 때문)
    • 아래의 코드는 "World!"를 출력할 때까지 기다리지 않고 "Hello,"를 출력한 후에 바로 종료된다.
    fun main() = runBlocking {
        GlobalScope.launch {
            delay(1000L)
            println("World!")
        }
        println("Hello~")
    }
    // Hello~

     

    public fun <T> runBlocking(
        context: CoroutineContext = EmptyCoroutineContext,
        block: suspend CoroutineScope.() -> T
    ): T
    
    public fun CoroutineScope.launch(
        context: CoroutineContext = EmptyCoroutineContext,
        start: CoroutineStart = CoroutineStart.DEFAULT,
        block: suspend CoroutineScope.() -> Unit
    ): Job
    
    public fun <T> CoroutineScope.async(
        context: CoroutineContext = EmptyCoroutineContext,
        start: CoroutineStart = CoroutineStart.DEFAULT,
        block: suspend CoroutineScope.() -> T
    ): Deferred<T>
    • launch와 async 빌더는 CoroutineScope 의 확장함수이다.
    • runBlocking, launch, async 함수를 살펴보면 block 파라미터가 모두 Coroutine을 리시버로 받는 확장 함수로 받는다.
    • 이러한 사실은 각 스코프 내에서 GlobalScope를 제거하고 launch만 호출이 가능하다는 것을 알 수 있다.
    • GlobalScope를 제거하면 launch는 runBlocking의 자식 코루틴이 되고, 부모 코루틴이 된 runBlocking은 자식 코루틴의 종료를 기다리게 된다.
    • 위에서 살펴보았던 예시 코드에서 GlobalScope를 제거하고 launch만 선언하면 runBlocking은 자식 스코프인 launch를 기다리게 되어 "World!"까지 모두 출력되는 것을 확인할 수 있다.
    fun main() = runBlocking {
        launch {
            delay(1000L)
            println("World!")
        }
        println("Hello~")
    }
    // Hello~
    // (1 sec)
    // World!
    • 부모 코루틴은 자신의 스코프를 자식에게 전달하고, 자식 코루틴은 해당 스코프에서 호출을 받는다. 이러한 부모-자식 간의 관계를 생성하는 것을 structured concurrency라고 한다.
    • 부모-자식간의 관계에 대한 상호작용은 다음과 같다.
      • 자식 코루틴은 부모 코루틴으로부터 컨텍스트를 상속받는다. (하지만 해당 컨텍스트를 덮어쓰는 것도 가능하다.)
      • 부모 코루틴은 자식 코루틴이 모두 완료될 때까지 일시중단된다.
      • 부모 코루틴이 cancel되었을 때, 자식 코루틴들도 모두 cancel 된다.
      • 자식 코루틴에서 예외가 발생하여 부모 코루틴으로 전파되었을 때, 부모 코루틴 또한 종료된다.
    • 다른 coroutine builder들과 다르게 runBlocking은 CoroutineScope의 확장함수가 아닌 것을 위의 정의에서 확인할 수 있다.
    • 이는 runBlocking이 자식 코루틴은 될 수 없고, 오로지 root 코루틴만 될 수 있다는 것을 의미한다.

    참고자료

    https://www.amazon.com/Kotlin-Coroutines-Deep-Marcin-Moskala/dp/8396395837

    반응형

    댓글

Designed by Tistory.