탐비의 개발 낙서장

[Kotlin] 코틀린 Coroutine 기본 요소 본문

프로그래밍/Kotlin

[Kotlin] 코틀린 Coroutine 기본 요소

탐비_ 2021. 8. 3. 22:57
Coroutine 개념

 

 프로세스 - 스레드 간 관계와, 스레드 - 코루틴 관계를 비슷하게 볼 수 있습니다. 코루틴은 경량 스레드라고 하며, 스레드와 비슷한 라이프사이클을 가지고 있지만, 스레드 안에서 실행됩니다. 스레드 하나에 많은 코루틴이 있을 수 있지만 주어진 시간에 하나의 스레드에서 하나의 명령만이 실행될 수 있습니다.

 예를 들어, 같은 스레드에 10개의 코루틴이 있다면, 해당 시점에는 하나의 코루틴만 실행되는 방식입니다.

 

 스레드와의 비교해 보자면, 비동시 프로그래밍시 스레드를 신중하게 다뤄야 하는 이유가 스레드 생성 및 해제, Context-Switching시 CPU의 메모리를 소모해 많은 수의 스레드를 갖는데 어려움이 있고, 메인 스레드에서 일정시간 한가지 TASK를 수행하면 ANR에러가 발생하기 때문입니다.

 그에 반해 코루틴은 스레드가 아닌 서브 루틴을 일시정지(suspend)시키는 방식으로 Context-Switching 비용이 발생하지 않아 경량 스레드라는 이름에 맞게 동작합니다.

 

 

Coroutine 핵심 요소

 

CoroutineScope

 

CoroutineScope 는 말 그대로 코루틴의 범위, 코루틴 블록을 묶음으로 제어할수 있는 단위입니다.

 

- Global Scope : 앱의 생명주기와 함께 동작하기 때문에 별도로 생명 주기의 관리가 필요 없습니다. 시작~종료까지 긴 기간동안 실행되는 코루틴의 경우에 적합합니다.

- Coroutine Scope : 버튼을 눌러 다운로드 / 서버에서 이미지 열기 등 필요할 때만 열고 완료되면 닫아주는 코루틴 스코프를 사용 가능합니다. LiveData 등의 생명 주기와 함께 유지되도록 하는데 응용할 수 있습니다.

 

CoroutineContext

 

CoroutineContext 는 코루틴을 어떻게 처리 할것인지 에 대한 여러가지 정보의 집합입니다.

CoroutineContext 의 주요 요소 로는 Job 과 dispatcher 가 있습니다.

 

Dispatcher

 

Dispatcher 는 CoroutineContext 의 주요 요소 입니다.

CoroutineContext 을 상속받아 어떤 스레드를 이용해서 어떻게 동작할것인지를 미리 정의해 두었습니다.

 

- Dispatchres.Default : CPU 를 많이 사용하는 무거운 작업을 할때 사용합니다.

- Dispatchers.IO : 네트워크 통신이나, 내부디비를 다루는 가벼운 작업시 사용합니다. 메인스레드에 영향을 주지 않기 때문에 UI를 그리는일 외 대부분 작업을 실행할때 사용합니다.

- Dispatchers.Main :메인스레드에서 동작하기 때문에 대기 시간이 있을 경우 앱이 ANR이 발생할 수 있어 UI업데이트와 같이 즉각적인 작업을 실행할때 사용합니다.

 

Coroutine Builder

 

1. launch 

- job 객체를 return 합니다.

- job은 코루틴의 작업 단위를 뜻하며 job을 이용해 실행중인 코루틴을 취소할수 있고, join()을 이용하여 job이 실행이 완료될때 까지 기다리게 할수 있습니다. 

 

2. async

- 실제 값을 반환합니다.

- await()를 사용해 실행중인 스레드를 멈추고 결과를 반환할때까지 기다립니다. (job.join과 동일). await() 예제는 위의 코드중에 있습니다.

 

3. runBlocking

- 별도 설정이 없어도 결과값을 반환할때까지 스레드를 중지시킵니다. 

- Scope지정 없이도 코루틴을 생성한다.

- 스레드를 중지시키기 때문에 메인스레드에서 사용할땐 주의해야 합니다.

 

4. withContext

- 코루틴에서 Dispacher를 변경할때 사용한다. ( 이때 스레드도 변경된다. ) 

- 결과 값을 반환할때 까지 기다린다. ( async + awaite()와 동일 ) 

 

 

# 아직 Global Scope와 Coroutine Scope의 차이가 명확하게 이해되지가 않음.. Dispatcher도 선택하는 방법 등을 더 찾아봐야 할듯함. 코루틴보다 메인이 먼저 종료시 확인할 방법이 없어 디버깅이 어렵고 join/await를 써도 괜찮은지 등의 고민이 더 필요함.