[Kotlin] Coroutine의 Dispatcher란 무엇인가

박상군·2024년 10월 30일
0

Kotlin

목록 보기
7/9
post-thumbnail

dispatch = 보내다?

코틀린으로 비동기 처리 시 이제는 거의 기본이 되어버린 코루틴..
이 코루틴에서 자주 보이는 Dispatcher란 무엇인가..?

Dispatcher는 스레드를 관리하는 추상화 계층으로, 스레드 풀을 통해 스레드 리소스를 효율적으로 할당하고, 코루틴이 어떤 스레드나 스레드 풀에서 실행될지를 결정하는 역할을 하고, 실제 스레드는 코루틴의 스케줄러가 관리한다.

즉 개발자가 직접 스레드를 관리할 필요 없이 좀 더 쉽게 비동기 처리를 하도록 도와주는 매개체이다.

Dispatcher의 종류

1. Dispatchers.Main

  • 메인(UI) 스레드에서 코루틴을 실행

  • 주로 UI 관련 작업에 사용되며, 메인 스레드는 리소스가 제한적이므로, 시간이 오래 걸리는 작업을 여기에서 실행하면 앱이 멈추거나 느려질 수 있다.

2. Dispatchers.IO

  • I/O 작업에 최적화된 스레드 풀에서 코루틴을 실행
    여러 I/O 작업(파일 읽기/쓰기, 네트워크 요청, 데이터베이스 작업 등)에 적합하며, 필요에 따라 스레드를 많이 생성할 수 있다.

  • 네트워크 요청과 같은 느린 I/O 작업
    파일 입출력, 데이터베이스 쿼리 등 비동기적 I/O 작업

  • 스레드 수에 제한이 없어, 많은 동시 I/O 요청을 처리해야 하는 경우 적합하다.

3. Dispatchers.Default

  • CPU 집약적 작업에 최적화된 스레드 풀에서 코루틴을 실행
    CPU 코어 수에 맞추어 기본적으로 스레드를 생성하므로, 대규모 계산 작업에 적합하다.

  • 복잡한 계산, 예를 들어 배열, 리스트를 처리하거나 무거운 수학 연산을 수행할 때
    데이터 처리, 정렬, 필터링 등 CPU 사용량이 높은 작업

  • 일반적으로 CPU 코어 수에 맞추어 스레드 수를 제한하여 사용하기 때문에, 동시에 많은 작업이 발생하지 않도록 CPU 사용량을 관리할 수 있다.

4. Dispatchers.Unconfined

  • 특정 스레드에 구속되지 않고 현재 스레드에서 시작하여 실행
    코루틴이 처음 시작될 때는 호출한 스레드에서 실행되지만, suspend 함수가 호출되면 재개 시점에 따라 다른 스레드에서 실행될 수도 있다.

  • 테스트 및 간단한 코루틴 작업에서만 사용
    코루틴의 스레드 전환이 필요 없고, 특정 디스패처에 의존하지 않는 작업

  • 예상치 못한 스레드에서 실행될 수 있으므로 장기 실행 작업이나 복잡한 작업에는 권장되지 않는다. 특히, UI 업데이트가 필요한 작업에는 적합하지 않다.

5. newSingleThreadContext와 newFixedThreadPoolContext

  • 개발자가 특정한 스레드 풀을 생성하여 코루틴을 실행하도록 하는 방법입니다. 주로 커스텀 스레드가 필요하거나 특정한 스레드에서 작업을 격리해야 할 때 사용합니다.

  • 특정 작업을 고립된 스레드에서 실행해야 하는 경우
    고정된 스레드 풀에서 작업을 실행하고자 할 때

  • newSingleThreadContext는 하나의 스레드만을 사용하는 고립된 작업에 적합합니다. 작업이 끝나면 반드시 close()를 호출해 스레드를 정리해야 합니다.

Dispatcher와 스레드 할당의 원리

그렇다면 디스패쳐가 직접적으로 스레드를 할당하는가? X

디스패쳐가 직접적으로 스레드를 할당하지는 않고, 디스패쳐는 코루틴이 어느 스레드나 스레드 풀에서 실행될지를 결정하는 역할을 하고, 실제 스레드는 코루틴의 스케줄러가 관리한다.

디스패쳐는 스레드를 관리하는 추상화 계층으로, 스레드 풀을 통해 스레드 리소스를 효율적으로 할당하도록 돕고 코루틴이 시작될 때, 디스패쳐는 설정된 정책에 따라 해당 작업을 수행할 스레드를 선택하거나, 기존 스레드를 재사용하여 스레드 풀을 통해 코루틴을 효율적으로 관리하는 역할을 한다.

예를 들어:

Dispatchers.IO는 스레드 풀을 사용하여 여러 I/O 작업을 동시 실행할 수 있도록 스레드를 관리한다. 실제 스레드 풀은 스레드 수를 동적으로 늘리거나 줄일 수 있어, I/O 작업을 필요에 따라 조절합니다.

Dispatchers.Default는 CPU 집약적인 작업에 최적화된 스레드 풀을 제공하며, 시스템의 CPU 코어 수에 따라 스레드를 할당한다.

Dispatchers.Main은 메인(UI) 스레드를 가리키지만, 코루틴을 직접 메인 스레드에 할당하지 않고 메인 스레드의 Looper나 이벤트 루프를 사용하여 코루틴을 예약한다.

실제 스레드 할당과의 차이

디스패쳐 자체가 스레드를 할당하는 것이 아니라, 코루틴의 실행 위치를 지정하고, 스케줄러가 이를 기반으로 스레드 풀에서 스레드를 할당하여 실행한다.

이를 통해 여러 코루틴이 효율적으로 스레드를 공유할 수 있어 리소스 사용의 최적화가 가능한 것이다.

디스패쳐는 단지 코루틴이 특정 스레드 풀에서 실행되도록 지정할 뿐이며, 스케줄러가 이 요청을 받아들여 적절한 스레드를 할당한다.


Reference

kotlin-coroutines

0개의 댓글