본문 바로가기

소프트웨어-이야기/프로그래밍 언어와 프레임워크

코루틴 이해하기

(1) Thread의 한계 이해하기

Thread Blocking

  • 스레드가 아무것도 하지 못하고 사용될 수 없는 상태를 말한다.
  • 스레드는 비싼 자원이다. 이런 상황이 반복되면 애플리케이션의 성능이 크게 떨어진다.
var chatgptfuture: Future<ChatGptResponse> executorService.submit<ChatGptResponse> {
      // 오래 걸리는 작업
      // 만약 API 호출이 1분이상 소요된다면, thread는 1분간 점유된다. 
}
var result = chatgptfuture.get()
executorService.shutdown()

 

한계
  • 스레드는 생성 및 작업 전환 비용이 높다.
  • 스레드는 보유한 스레드풀 개수만큼 병렬로 실행할 수 있다. 
  • 멀티스레드 프로그래밍으로 스레드를 재사용하더라도, Thread Blocking 을 피하기 어렵다. 

 

(2) 코루틴

runBlocking 이란?

import kotlinx.coroutines.runBlocking

fun main() = runBlocking<Unit>{
    println("Hello World!")
}

해당 함수를 호출한 스레드를 사용해 실행되는 코루틴을 만든다. main 함수를 통해 실행되는 프로세스는 기본적으로 메인 스레드 상에서 실행된다. 위의 runBlocking 함수는 메인 스레드를 점유하는 코루틴을 만든다. 그리고 선언한 람다식 함수 실행이 완료될 때까지 코루틴은 종료되지 않는다. 

runBlocking 함수는 생성된 코루틴 실행이 완료될 때까지 다른 작업이 스레드를 점유하지 못하게 막는다. (blocking) 즉, 위의 코드는 메인 스레드를 점유하는 코루틴을 만들고, 코루틴이 실행 완료되어야 코루틴의 메인 스레드가 점유가 종료되고 프로세스가 종료된다. 

CoroutineContext 이란?

코루틴을 실행하는 실행 환경을 설정하고 관리하는 인터페이스이다. CoroutineDispatcher, CoroutineNamae, Job, CoroutineExcpetionHanler 등이 주요 구성요소이다. 

Structed Concurrency 이란?

구조화된 동시성의 원칙이란, 비동기 작업을 구조화하여 비동기 프로그래밍을 안정적이고 예측 가능하게 만드는 원칙을 말한다. 코루틴은 비동기 작업인 코루틴을 부모-자식 관계로 구조화하여, 코루틴이 안전하게 제어될 수 있도록 하였다. 

구조화된 코루틴의 특성은 다음과 같다.

  1. 코루틴으로 취소 요청이 들어오면, 자식 코루틴으로 전파된다.
  2. 부모 코루틴은 모든 자식 코루틴이 실행 완료되어야 완료될 수 있다.

 

참고

코틀린 코루틴의 정석