coroutine dispatchers, Flow Hot & Cold

2023. 6. 13. 00:14Coroutine

이번에는 coroutine의 context와 dispatchers에 대해 알아보자.

 

공홈

https://kotlinlang.org/docs/coroutine-context-and-dispatchers.html

 

Coroutine context and dispatchers | Kotlin

 

kotlinlang.org

 

예제 1

launch 4개를 생성하고 개별로 Dispatchers를 지정한다. 무언가 하는데 아직 잘 이해가 안 된다. 

Coroutine context는 무엇이고 Dispatcher는 어떤 역할을 하는 걸까? 먼저 아래에 작동 결과를 보자.

 

결과

1번 dispatcher가 지정되지 않은 launch의 출력 결과는 main Thread, coroutine#2에서 task를 처리한다.

2번은 Dispatcher.UnConfined는 main Thread의 coroutine#3에서 처리한다.

3번은 Dispather.Defaults는 DefaultDispatcher-worker-2의 coroutine#4에서 실행한다.

4번은 newSingleThreadContext("MyOwnThread")는 MyOwnThread라고 이름 된 coroutine#5에서 실행한다.

 

1번 지정하지 않으면 launch가 실행된 Scope의 Context를 따라 진행한다. 여기서 runBlocking은 Main Thread를 따른다. 그러므로 아무것도 지정하지 않으면 main Thread 그대로 사용한다.

 

2번 Unconfined 이건 설명을 읽어보면 이렇게 나와있다.

제한적이지 않아 main에서 실행되는 것 같아 보이지만 실제로 어디서 시작할지 모른다고 한다. 아래에 예를 보자.

첫 번째는 main이지만 뒤에서는 다른 스레드에서 동작한다. 그래서 특정하지 않다는 뜻이다.

4번은 싱글 스레드의 이름을 정해 새롭게 만들어서 작업할 수 있다.

 

위의 예와 결과를 토대로 Dispatcher는 coroutine에서 할 task들을 어떤 thread에서 실행할지 지정하는 관리 역할로 보인다.

 

 

Flow 

https://kotlinlang.org/docs/flow.html#representing-multiple-values

 

Asynchronous Flow | Kotlin

 

kotlinlang.org

 

예제 1

첫 번째 예제이다. 

여러 값을 반환하는 예제를 보여주고 있다. 왜 이러한 예제를 보여줬을까?

지금까지 예제를 보면 간단한 작동부터 필요한 이야기를 풀어나가고 있다. 여기서 보여주고 싶은 건 여러 개의 값을 어떻게 비동기적으로 반환하고 사용할 수 있을까를 보여주려고 한다.

 

위의 코드는 simple 함수가 있고 반환값은 list 1,2,3을 반환한다. 그리고 메인함수에 simple 코드의 반환을 forEach를 통해 반복하여 각 element를 출력한다. 

 

원하는 작동은 

1. 어떤 여러 개의 값을 가진 or 반환하는 함수가 있고

2. 이러한 함수의 값을 읽어온다.

 

다음 예제를 보자

 

예제 2

Sequences

Sequences는 CPU의 자원을 많이 사용하는 blocking code로 계산하는 경우 Sequences를 사용하여 나타낼 수 있다고 한다.

코드를 보자.

 

 

하나의 연산이 최소 100ms 걸린다고 가정하고 Thread를 sleep 한다.

그리고 yield로 값을 내보냅니다.

 

main에서는 반복문을 통해 simple 함수의 값을 사용하여 출력합니다.

하지만 위의 과정은 main Thread를 Block 합니다.

 

예제 3 Suspend func

suspend func을 사용하면 스레드를 차단하지 않고 비동기 작업을 수행한다고 합니다. 

 

위에 3개의 작업이 말하는 건 list를 반환할 때 thread를 차단하냐 값을 어떻게 반환할 건지에 대해 말하는 것 같다.

다음 Flow를 보면 확실히 이해가 갈 것 같다.

 

예제 4 Flows

 

지금까지 simple 함수는 list를 반환한다고 한다. 이때 한 번에 리스트를 반환한다고 하는데 이러한 비동기적인 작업의 스트림을 위해 동기적으로 하는 것처럼 하려면 Flow를 사용한다고 한다. 

 

그러니까 Flow를 사용하면 비동기로 처리되는 일련의 연속적인 값의 반환 과정을 동기적으로 계산되는 것처럼 해준다는 말인가? 예를 한번 보자.

 

일단 simple 함수의 반환이 Flow가 되었다. Flow는 비동기값을 동기적으로 반환하는 방식이라고 한다.

반복문 안에 delay가 뭔가 앱 안에서 데이터를 처리하거나 무언가 작업을 하는 거라 가정하고 결과가 나오면 emit i를 통해 값을 반환한다.

 

과정을 보면 가운데 launch에서 print를 하면서 simple함수를 collect 한다. 이때 i'm not blocked와 simple 함수의 emit(i)가 같이 동작한다 이를 통해 main thread가 막히지 않았음을 알 수 있다.

 

그리고 Flow는 Cold Stream이라고 한다. Cold? Stream은 어떤 의미인지 대충 알겠다. 그런데 Cold는 뭐지?

차갑다고? 

 

Flow는 collect로 사용해 값을 반환한다.

실행이 되기 전까지 값을 반환하지 않는다 = 실행이 돼야만 값을 반환한다.

두 번의 flow collect가 있다. 두 번다 따로 시작하여 별개의 스트림이 생성된다. Hot Stream은 하나의 스트림을 여러 개의 collector가 공유하고 동일한 데이터를 수집한다고 한다. Cold의 개념이 어느 정도 잡힌다. 

 

그래서 왜 Cold일까...? 

Hot Stream을 생각하면 Hot Stream은 항상 데이터를 최신 상태로 유지한다. 라디오라고 생각하면 된다. 

누가 듣는지 알 필요가 없다. 라디오는 누가 듣는지 몇 명이 듣는지 신경 쓰지 않고 방송을 시작하면 계속 송출한다. Stream이 항상 On인 상태 항상 Hot한 상태라 Hot인 것 같다. 반면에 Cold는 요청해야 값을 보내준다. 그래서 그런가 Cold 차갑다?라는 표현을 쓴 것 같다. 누가 달라고 하지 않으면 주지 않는 그런 차가운 녀석인가 보다.

 

이번 글로 flow의 기본적 개념과 Cold, Hot의 개념을 어느 정도 잡게 되었다.

 

 

'Coroutine' 카테고리의 다른 글

coroutine suspend function, async, await  (0) 2023.06.12
coroutine basic  (0) 2023.06.10
Coroutine 기본 개념잡기  (0) 2022.12.27