개발 언어/코틀린

kotlin - coroutine (부록1) launch VS coroutineScope

jjiiiinn 2024. 9. 5. 15:01
728x90

1. launch란?

launch새로운 코루틴을 시작하는 코루틴 빌더입니다. 비동기적으로 작업을 시작하며, 결과를 반환하지 않는다는 점에서 async와 차별됩니다.

  • 코루틴을 시작하는 함수로, 실행된 코루틴은 비동기로 동작합니다.
  • 경량 스레드와 비슷한 개념으로, 별도의 스레드를 차지하지 않고 코루틴이 독립적으로 실행됩니다.
  • launch로 생성된 코루틴은 결과값을 반환하지 않으며, 종료된 시점을 명시적으로 기다리거나 확인할 필요가 없을 때 사용합니다.

간단한 예제 (launch):

import kotlinx.coroutines.*

fun main() = runBlocking {
    // launch를 사용해 새로운 코루틴을 시작
    launch {
        delay(1000L)
        println("Task from launch")
    }

    println("Main program continues...")
}

설명:

  • launch코루틴을 시작하고, 비동기적으로 작업을 실행합니다.
  • 이 코루틴은 1초 동안 지연되며, 그동안 main 함수는 계속해서 실행됩니다.

2. coroutineScope란?

coroutineScope하나의 코루틴 스코프를 생성하고, 그 스코프 내에서 실행되는 모든 코루틴을 관리하는 함수입니다. 모든 자식 코루틴이 완료될 때까지 대기하며, 스레드를 차단하지 않습니다.

  • 코루틴을 구조화하고 관리하는 역할을 합니다. 이 스코프 내에서 발생하는 모든 코루틴이 완료될 때까지 스코프가 종료되지 않습니다.
  • coroutineScope는 스레드를 차단하지 않으며, 비동기 함수에서 사용됩니다.
  • coroutineScope 내에서는 여러 개의 launch를 사용하여 코루틴을 생성할 수 있으며, 모든 코루틴이 완료될 때까지 기다린 후 종료됩니다.

간단한 예제 (coroutineScope):

import kotlinx.coroutines.*

suspend fun myFunction() = coroutineScope {
    launch {
        delay(1000L)
        println("Task from launch in coroutineScope")
    }

    println("Coroutine scope is active")
}

fun main() = runBlocking {
    myFunction()
    println("Main program ends")
}

설명:

  • coroutineScope하나의 코루틴 스코프를 만들고 그 안에서 자식 코루틴들을 실행합니다.
  • coroutineScope는 자식 코루틴들이 모두 완료될 때까지 종료되지 않고 기다립니다.
  • 여기서는 launch를 사용하여 코루틴을 실행했지만, 코루틴의 실행과 종료를 coroutineScope가 관리합니다.

3. coroutineScopelaunch의 차이점

기능 / 특성 launch coroutineScope
역할 새로운 코루틴을 시작하는 코루틴 빌더 코루틴 스코프를 관리하는 구조
비동기 실행 여부 비동기적으로 코루틴을 실행 내부에서 코루틴을 실행하고 그들을 관리
종료 조건 코루틴이 끝나면 자동 종료 모든 자식 코루틴이 끝날 때까지 대기
스레드 차단 여부 스레드를 차단하지 않음 스레드를 차단하지 않음
사용 목적 하나의 독립된 코루틴 실행 여러 코루틴을 구조화하고 관리할 때 사용
예외 처리 예외 발생 시 부모 스코프에 전파됨 스코프 전체에서 예외 처리 가능
코루틴 실행 코루틴을 실행하고 비동기 작업을 시작함 자식 코루틴들을 실행하고 그들의 상태를 관리

주요 차이점:

  1. launch는 새로운 코루틴을 시작하는 도구일 뿐이고, coroutineScope는 코루틴들의 구조와 수명을 관리하는 데 목적이 있습니다.
  2. launch는 단독으로 사용될 수 있지만, coroutineScope자식 코루틴들이 제대로 관리되는 구조를 제공하고, 내부에서 여러 launch를 사용해 코루틴을 생성할 수 있습니다.
  3. launch비동기 작업을 시작하고 결과를 반환하지 않으며, 코루틴의 동작을 더 이상 신경 쓸 필요가 없는 경우에 사용됩니다. 반면, coroutineScope는 비동기 작업을 안전하게 관리하며, 모든 작업이 완료될 때까지 기다린 후 종료됩니다.

4. 비유를 통해 이해하기

비유적으로 설명하자면, launch는 단순히 일을 시키는 개별 작업자라고 생각할 수 있습니다. 하지만 coroutineScope그 작업자들을 관리하는 감독자 같은 역할을 합니다.

  • launch는 작업자 한 명을 데려와서 일하게 하고, 그 작업이 끝나면 그냥 일을 마무리하는 개념입니다.
  • coroutineScope는 여러 작업자(launch를 통해 만든 코루틴)들을 한 그룹으로 묶어 관리하고, 모든 작업이 끝날 때까지 이 그룹을 관리하는 역할을 합니다.

5. 실전 예시: launchcoroutineScope의 결합

coroutineScope는 여러 개의 코루틴을 구조적으로 관리할 때 사용되며, 그 안에서 여러 개의 launch를 통해 코루틴을 생성하고 관리할 수 있습니다. 이 구조를 통해 비동기 작업을 체계적으로 관리할 수 있습니다.

import kotlinx.coroutines.*

suspend fun structuredConcurrencyExample() = coroutineScope {
    launch {
        delay(1000L)
        println("Task 1 from coroutineScope")
    }

    launch {
        delay(500L)
        println("Task 2 from coroutineScope")
    }

    println("Coroutine scope is active")
}

fun main() = runBlocking {
    structuredConcurrencyExample()
    println("Main program ends")
}

설명:

  • coroutineScope는 두 개의 launch로 코루틴을 실행하고, 이 두 코루틴이 완료될 때까지 기다린 후 종료됩니다.
  • 모든 코루틴이 완료될 때까지 coroutineScope는 종료되지 않으며, 완료되면 메인 스레드로 돌아가서 "Main program ends"를 출력합니다.

출력:

Coroutine scope is active
Task 2 from coroutineScope
Task 1 from coroutineScope
Main program ends

요약

  1. launch비동기 작업을 시작하는 빌더이며, 별도로 구조적인 관리 기능을 제공하지 않습니다. 개별적으로 사용하여 코루틴을 실행하는 데 적합합니다.
  2. coroutineScope코루틴의 수명과 구조를 관리하는 스코프를 제공하며, 내부에서 여러 개의 launch를 사용하여 코루틴을 실행하고, 모든 자식 코루틴이 완료될 때까지 기다립니다.
  3. coroutineScope는 비동기 작업의 구조화된 동시성(Structured Concurrency)를 구현하는데 핵심적인 역할을 하며, 이를 통해 비동기 작업을 안전하고 관리하기 쉽게 만들어줍니다.
728x90