Coroutines 일시중단 함수 구성하기 1편 - 기본적인 순차 처리, async를 사용한 동시성, async lazy하게 시작하기

2023. 2. 18. 22:30·공식 문서 번역/Coroutines 공식 문서
반응형

이 섹션은 일시 중단 함수를 구성하기 위한 다양한 접근 방식을 다룬다.

 

기본적인 순차 처리

일종의 원격 서비스 호출이나 계산 같은 두 유용한 일시 중단 함수들이 서로 다른 위치에 정의되어 있다고 가정해보자. 이들은 유용한척 하지만 실제로는 이 예제의 목적을 위해 1초간 delay가 일어난다.

 

suspend fun doSomethingUsefulOne(): Int {
    delay(1000L) // pretend we are doing something useful here
    return 13
}

suspend fun doSomethingUsefulTwo(): Int {
    delay(1000L) // pretend we are doing something useful here, too
    return 29
}

 

먼저 doSomethingUsefulOne을 호출하고 doSomethingUsefulTwo을 호출한 다음 결과의 합계를 계산해야 하는 경우 이들을 순차적으로 실행되도록 하기 위해서 어떤 것을 해야할까? 이런 작업은 첫 째 함수의 결과를 사용해 둘 째 함수를 호출해야 하는지 혹은 어떻게 호출 할지를 결정해야 할 때 사용된다.

 

Coroutine 코드는 일반적인 코드와 같이 기본적으로 순차적이기 때문에, 일반적인 순차 호출을 사용한다. 다음 예제는 두 일시 중단 함수들을 실행하는데 걸리는 총 시간을 측정하여 보여준다.

 

val time = measureTimeMillis {
    val one = doSomethingUsefulOne()
    val two = doSomethingUsefulTwo()
    println("The answer is ${one + two}")
}
println("Completed in $time ms")

📌 전체 코드는 이곳에서 확인할 수 있습니다.

 

이 코드는 다음의 결과를 출력한다.

The answer is 42
Completed in 2017 ms

 


이 글은 Coroutines 공식 문서를 번역한 글입니다.

 

원문 : Composing suspending functions - Sequential by default

원문 최종 수정 :  2022년 6월 27일

 


async를 사용한 동시성

만약 doSomethingUsefulOne과 doSomethingUsefulTwo의 실행 사이에 종속성이 없고, 이 둘을 동시에 실행함으로써 응답을 더 빨리 얻고 싶다면 어떻게 해야할까? 여기에서 async가 사용될 수 있다.

 

개념적으로 async는 launch와 같다. async는 다른 스레드들과 동시에 동작하는 별도의 경량 Thread인 Coroutine을 시작한다. 다른 점은 launch는 결과값을 전달하지 않는 Job을 return 하지만, async는 나중에 결과값을 반환할 것을 약속하는 경량이고 Blocking을 하지 않는 Future*1인 Deffered를 반환한다는 점이다. Deferred에 대해 .await() 함수를 사용해 결과값을 얻을 수 있지만, Deffered 또한 작업이라 필요할 때 취소될 수 있다.

 

val time = measureTimeMillis {
    val one = async { doSomethingUsefulOne() }
    val two = async { doSomethingUsefulTwo() }
    println("The answer is ${one.await() + two.await()}")
}
println("Completed in $time ms")

📌 전체 코드는 이곳에서 확인할 수 있습니다.

 

위 코드는 다음의 결과를 출력한다.

 

The answer is 42
Completed in 1017 ms

 

두 Coroutine들이 동시에 실행되기 때문에 두 배 정도 빠른 것을 볼 수 있다. Coroutines의 동시성은 언제나 명시적이다.


*1. Future이란 프로그래밍 언어에서 프로그램 실행을 동기화하려고 쓰는 구조체의 일종으로, 읽기 전용 플레이스 홀더(값)이다. Future의 값은 Promise(값을 쓰는 함수)에 의해 설정되며, 하나의 Future에 대해서는 한 번만 값이 설정될 수 있다.


이 글은 Coroutines 공식 문서를 번역한 글입니다.

 

원문 : Composing suspending functions - Concurrent using async

원문 최종 수정 :  2022년 6월 27일


async lazy하게 시작하기

선택적으로 첫 파라미터 값을 CoroutineStart.LAZY 로 설정함으로써 async를 lazy하게 만들 수 있다. 이 모드에서는 Coroutine의 결과값이 await에 의해 필요해지거나, Job의 start 함수가 실행될 때 시작된다. 다음 예를 실행해보자.

 

val time = measureTimeMillis {
    val one = async(start = CoroutineStart.LAZY) { doSomethingUsefulOne() }
    val two = async(start = CoroutineStart.LAZY) { doSomethingUsefulTwo() }
    // some computation
    one.start() // start the first one
    two.start() // start the second one
    println("The answer is ${one.await() + two.await()}")
}
println("Completed in $time ms")

📌 전체 코드는 이곳에서 확인할 수 있습니다.

 

이는 다음의 결과를 생성한다.

 

The answer is 42
Completed in 1017 ms

 

여기에는 두 개의 Coroutine이 정의되어 있지만 이전 예제*1와 같이 실행되지 않으며, 프로그래머에게 start를 사용하여 언제 시작할 것인지에 대한 제어 권한이 주어진다. 먼저 one을 실행한 다음 two를 시작하며, 각 Coroutine들이 끝날 때까지 기다린다.

 

await은 Coroutine을 시작하고 완료를 기다리도록 하기 때문에, 개별 Coroutine들에서 start를 호출하지 않고 println 함수 내부에서 await을 호출하면 순차 처리*2가 된다. 이는 지연 처리를 위한 의도된 유즈케이스가 아니다. async(start = CoroutineStart.LAZY)는 값의 연산을 위한 계산이 일시 중단 함수를 포함할 때 표준 lazy 함수를 대체한다.

 

 


아래의 내용들은 모두 독자의 이해를 위해 번역자가 추가한 내용입니다.

 

*1. 이전 예제 코드는 다음과 같다.

val time = measureTimeMillis {
    val one = async { doSomethingUsefulOne() }
    val two = async { doSomethingUsefulTwo() }
    println("The answer is ${one.await() + two.await()}")
}
println("Completed in $time ms")

이 예제에서 async는 선언되자마자 실행된다.

 

*2. 다음과 같이 println 내부에서

fun main() = runBlocking<Unit> {
    val time = measureTimeMillis {
        val one = async(start = CoroutineStart.LAZY) { doSomethingUsefulOne() }
        val two = async(start = CoroutineStart.LAZY) { doSomethingUsefulTwo() }
        println("The answer is ${one.await() + two.await()}")
    }
    println("Completed in $time ms")
}

 

다음의 결과가 출력된다.

그림1. println 내부에서 await을 수행하는 경우


이 글은 Coroutines 공식 문서를 번역한 글입니다.

 

원문 : Composing suspending functions - Lazily started async

원문 최종 수정 :  2022년 6월 27일

 


목차로 돌아가기

 

Kotlin Coroutines 공식 문서 한국어 번역본 : Coroutines 한 번에 정리하기

Kotlin Coroutines 공식 문서 번역을 시작하며 Kotlin Coroutines는 Kotlin을 위한 강력한 비동기 솔루션이다. 안드로이드 실무에서는 한동안 높은 점유율을 자랑한 RxJava를 Coroutines가 대체하고 있으며, 새로

simplecode.kr

 

반응형

'공식 문서 번역 > Coroutines 공식 문서' 카테고리의 다른 글

Coroutine Context와 Dispatcher 1편 - Dispatchers와 Threads, Unconfined vs confined dispatcher  (0) 2023.02.20
Coroutines 일시중단 함수 구성하기 2편 - 비동기 스타일 함수, 구조화된 동시성과 async  (0) 2023.02.19
Coroutines 실행 시간 제한하기 - Timeout, 비동기 Timeout과 리소스  (0) 2023.02.17
Coroutines 취소 2편 - finally를 사용해 리소스 닫기, 실행 취소가 불가능한 블록 실행하기  (0) 2023.02.16
Coroutines 취소 1편 - Coroutine 실행 취소하기, Coroutines 취소는 협력적이다, Coroutine의 Computation 코드를 취소 가능하게 만들기  (0) 2023.02.15


'공식 문서 번역/Coroutines 공식 문서' 카테고리의 다른 글
  • Coroutine Context와 Dispatcher 1편 - Dispatchers와 Threads, Unconfined vs confined dispatcher
  • Coroutines 일시중단 함수 구성하기 2편 - 비동기 스타일 함수, 구조화된 동시성과 async
  • Coroutines 실행 시간 제한하기 - Timeout, 비동기 Timeout과 리소스
  • Coroutines 취소 2편 - finally를 사용해 리소스 닫기, 실행 취소가 불가능한 블록 실행하기
심플코드
심플코드
프로그래밍을 어렵지 않게 풀어서 설명하는 기술 블로그
    반응형
  • 심플코드
    심플코드
    심플코드
  • 전체
    오늘
    어제
    • 분류 전체보기 (96)
      • 안드로이드를 위한 Coroutines (2)
      • Unit Testing (19)
      • GitHub Actions (0)
      • 공식 문서 번역 (35)
        • Coroutines 공식 문서 (35)
      • 알고리즘 (7)
        • Kotlin 자료구조 (0)
        • 알고리즘 (7)
        • Kotlin으로 구현하는 자료구조 (0)
      • 코딩 테스트 (0)
      • Deep Learning (0)
      • Machine Learning Math (17)
        • Linear Algebra (17)
      • ML (0)
      • Docker (15)
      • Kubernetes (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

    • 코틀린 코루틴의 정석 책 출간 소식
  • 인기 글

  • 태그

    Docker
    mockito
    컨테이너
    Coroutines Channel
    Coroutines Flow
    코루틴 Flow
    Coroutines Context
    numpy
    Kotlin
    unit testing
    junit
    unit test
    코루틴 채널
    도커
    Machine Learning
    TensorFlow
    코루틴
    Coroutines
    coroutine
    pytorch
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
심플코드
Coroutines 일시중단 함수 구성하기 1편 - 기본적인 순차 처리, async를 사용한 동시성, async lazy하게 시작하기
상단으로

티스토리툴바