-
[Kotlin] Coroutine과 Multi-ThreadKotlin 2022. 10. 25. 00:44
코틀린 언어에서는 Coroutine이란 개념이 있습니다. 코틀린의 강점으로 많이 언급되는 개념으로,
멀티 스레드와 비슷하지만 다르다고만 알고있어서, 좀 더 자세한 이해가 필요하다고 생각되어 학습한 내용을 블로그에 정리해 둡니다.
Process와 Thread, 그리고 Multi-Thread
Coroutine을 이해하기에 앞서, 먼저 프로세스와 스레드에 대한 개념부터 정리합니다.
Thread는 단어 자체의 의미로는 '실'이라는 뜻입니다. 프로그래밍에서는 실행흐름을 뜻합니다.
Process는 메모리에 올라와 실행되고 있는 프로그램의 인스턴스입니다. 독립적인 개체로, 각각의 프로세스는 독립된 Heap 메모리 영역을 할당받습니다. 프로세스는 최소 1개의 스레드(이를 '메인스레드'라고 칭합니다.)를 가지게 됩니다.
"프로세스는 최소 1개의 스레드를 가지게 된다"에서 알 수 있듯이, 스레드는 프로세스의 하위에 종속되는 단위입니다. 각 스레드는 독립된 Stack 메모리 영역을 가집니다. 프로세스의 힙 메모리 영역은 모든 스레드가 공유할 수 있고, 스레드끼리는 스택 메모리를 공유할 수 있습니다.
멀티 스레드의 경우, 하나의 프로세스에 스레드가 2개 이상인 경우를 뜻합니다.
Coroutine이란? (Coroutine ≠ Thread)
코틀린 공식문서에는 코루틴을 그저 light-weight thread(경량화 된 스레드)라고 생각할 수도 있지만, 스레드와 확실히 구분되는 주요사항들이 있다고 설명합니다.
코루틴은 작업 각각에 Coroutine Object를 할당합니다. 객체이기 때문에 Heap 메모리에 적재됩니다.
작업의 단위를 Object로 축소하면서 하나의 스레드가 여러개의 코루틴을 가질 수 있습니다. 이를 정리하면,
하나의 Process는 여러개의 Thread를 가집니다. 그리고 하나의 Thread는 다시 여러개의 Coroutine을 가집니다.
제가 생각하기에 가장 핵심이 되는 한 문장이라 생각합니다.
Multi-Thread 방식의 한계점
멀티 스레드는 동시에 여러 작업을 수행할 수 있습니다. 그러나 여기엔 한계점이 존재합니다.
#1. 단위가 Thread이다.
Thread는 비싼 자원입니다. 비싼 자원을 많이 사용할 수록 메모리 낭비가 심하므로, 가급적이면 이러한 자원들은 최소한의 사용으로 효율을 내는 것이 좋습니다.
#2. Blocking 문제
예를들어 한 스레드가 다른 스레드의 결과를 전달받아야만 진행될 때, 해당 스레드는 작업 결과를 받기 전까지는 대기상태가 됩니다. 이를 Blocking이라 하는데, 비싼 자원인 스레드가 아무 작업도 안하고 대기상태로 있기 때문에 자원이 낭비되는 문제가 발생합니다.
Coroutine을 사용한다면?
#1. 단위가 Thread인 것을 해소할 수 있다.
기존에는 여러 개의 작업을 동시에 처리하기 위해 비싼 자원인 스레드를 여러 개 만들어야 했습니다.
그러나 이제는 스레드 대신 코루틴을 사용하여 동시에 작업을 처리할 수 있습니다. 이 말은 스레드가 여러개일 필요가 없다는 뜻이기도 합니다!
단일 스레드 내에 여러 Coroutine Object를 두고, 작업단위를 코루틴으로 관리할 수 있습니다. 물론 멀티 스레드 환경에서도 코루틴을 가질 수 있지만, 단일 스레드 내에 여러개의 코루틴을 두는 방법을 코틀린에서는 권장하고 있습니다.#2. Blocking문제를 해소할 수 있다.
위에서 언급했던 한계점 #2의 멀티스레드 상황에서, 만약 스레드에 코루틴이 추가되어있다면 다음과 같이 작동하게 됩니다.
1. 스레드1은 코루틴 1, 2를 가집니다.
2. 스레드1의 코루틴1이 스레드2의 결과를 전달받아야 하는 작업A을 수행합니다. 이 때 스레드 2의 작업이 끝날 때 까지 코루틴1은 일시중단됩니다.
3. 스레드1의 코루틴2가 새로운 작업(작업B)을 수행합니다.
4. 스레드2에서 작업A'이 끝나고 결과를 코루틴1에게 전달하면, 코루틴1은 작업A를 재개합니다.
기존 스레드만 있었을 때는 작업A가 끝날 때 까지 다른 작업을 수행하지 못했습니다. 그러나 코루틴으로 관리하게 되니 작업A를 수행하는 동안에도 작업B를 수행할 수 있게 되었습니다.References::
https://kotlinlang.org/docs/coroutines-basics.html
https://velog.io/@haero_kim/Thread-vs-Coroutine-%EB%B9%84%EA%B5%90%ED%95%B4%EB%B3%B4%EA%B8%B0