Coroutine feat.Kotlin - Coroutine 기초

Tnalxmsk·2023년 11월 24일
0

코루틴

목록 보기
2/3

코루틴

코루틴이라는 말은 코틀린 언어에서만 지원하는 기술이라고 생각할 수 있지만, 다양한 프로그래밍 언어에서 지원하는 기능이다.
코루틴은 함께를 뜻하는 Co와 routine이 합쳐진 단어로 함께 동작하는 규칙이 있는 일의 순서를 뜻한다.
Android Developers에선 코루틴을 '비동기적으로 실행되는 코드를 간소화하기 위해 사용할 수 있는 동시 실행 설계 패턴' 이라고 설명한다.

일반적인 루틴

우리가 흔히 알고있는 루틴에 대해 코틀린 코드로 알아보자.

이 코드의 실행은 아주 직관적이다.
먼저 println("START")가 실행이 된 후 newRoutine() 함수를 실행하며 새로운 루틴에 진입한다. num1, num2가 지역 변수로서 초기화 되고 num1과 num2에 합이 출력된 후 루틴이 종료된다. println("END")가 출력된 후 실행이 종료된다.

코드 실행 결과를 통해 실행 루틴을 알 수 있다.

이를 그림으로 정리하면 다음과 같다.
메모리 관점에서 생각하면 새로운 루틴이 호출되면 newRoutine()이 사용하는 스택에 지역 변수가 초기화 되고 루틴이 끝나면 해당 메모리에 접근이 불가능하다.

하지만 코루틴은 이와 다르게 동작한다.

코루틴

먼저 코틀린에서 코루틴을 사용하기 위해 의존성을 추가해야 한다.

dependencies {
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.2'
}

이제 코드를 살펴보자

fun main(): Unit = runBlocking {
   println("START")    
   
   launch { 
       newRoutine()
   }
   yield()
   
   println("END")
}

suspend fun newRoutine() {
   val num1 = 1
   val num2 = 2
   yield()                
   println("${num1 + num2}")
}

runBlocking은 루틴과 코루틴 세계를 연결하는 역할을 하며 main을 새로운 코루틴으로 만든다.
launch는 비동기적으로 실행되는 새로운 코루틴을 만든다.
yield()는 현재 코루틴을 중단하고 스레드를 다른 코루틴에게 양보한다.

코드 실행 관점에서 나타내면 다음과 같으며, yield()를 통해 코루틴의 실행 흐름을 제어할 수 있다.
메모리 관점에서 새로운 루틴이 호출된 후 종료되기 전, 해당 루틴에서 사용했던 정보들을 보관한다. 루틴이 중단되면 정보를 가지고 있는 해당 메모리에 접근이 가능하다.

코드 실행 결과는 다음과 같다.
왜 실행 결과가 이렇게 나오는지 코드를 살펴보자!

프로그램을 실행하면 runBlocking에 의해 새로운 코루틴 1을 만든다. println("STRAT")가 가장 먼저 실행된다. 이후 launch 블럭에서 새로운 코루틴 2가 생성되고 newRoutine() 함수를 호출한다.
함수가 호출되면 num1, num2를 초기화하고 yield()에 의해 코루틴 2가 중단된다.
코루틴 1로 돌아와 println("END")를 실행 후 코루틴 2가 재개되어 num1 + num2를 출력하고 종료된다.

위 과정을 통해 프로그램은 START -> END -> 3 순으로 출력을 하게 된다.

루틴과 코루틴 정리

일반적인 루틴과 코루틴의 특징을 정리하면 다음과 같다.

  • 루틴
    • 시작되면 끝날 때까지 멈추지 않는다.
    • 한 번 끝나면 루틴 내의 정보가 사라진다.
  • 코루틴
    • 중단되었다가 재개될 수 있다.
    • 중단되더라도 루틴 내의 정보가 사라지지 않는다.

마무리

이번 포스트에선 코루틴의 아주 기초적인 부분에 대해 알아보았다.
다음 포스트에선 프로세스와 스레드, 코루틴에 대해 자세히 알아보자.

0개의 댓글