본문 바로가기
Mobile App

[안드로이드] - coroutine (코루틴) - 0

by Jman 2023. 1. 18.

코루틴을 알기 위하여, 프로그램 실행을 훑기

보통, 프로그램이 실행되는 과정을 한 번 정리를 해보자.

  • 프로그램이 실행이 되면, 실행된 코드가 메모리에 load 가 된다.
  • load 된 인스턴스를 프로세스라고 일컫는다.
  • 프로세스는 여러 개의 독립된 실행의 흐름을 갖게 된다.
  • 이 실행 흐름 하나하나를 Thread 라고 한다.
  • 프로세스는 자기가 사용하기 위해 메모리를 할당 받는다. 그걸 Heap 이라 한다.
  • 프로세스 안에서 돌아가는 각 각의 Thread 가 존재하는데, 그 스레드 메모리를 Stack 이라 부른다.
  • 또한, 스레드는 프로세스 안에 있는 Heap 안 자원을 각 Thread 끼리 공유할 수 있다.
  • 여기서 코루틴은 Thread Stack 을 할당을 받지 않고, 프로세스에 할당된 Heap memory 를 공유하여 사용하게 된다.

 

 

 

자세히 알아보기 위해서는 아래의 블로그를 참고하면 좋을 것 같습니다.

https://aaronryu.github.io/2019/05/27/coroutine-and-thread/

 

Coroutine, Thread 와의 차이와 그 특징

처음 Kotlin 를 사용하던 중에 비동기 처리를 위해 Coroutine 개념을 마주했었습니다. 동기란 요청을 보낸 후 요청에 대한 반환값을 얻기 이전까지 대기하는걸 의미하고, 비동기는 그 대기시간동안

aaronryu.github.io

 

위 블로그 개념을 읽고 오면 어느정도 정리가 됐을 것이다.

이제 코루틴에 대한 개념을 정리를 해보자.

 

 

코루틴 구성

Coroutine Scope : 코루틴이 어떤 범위에서 동작할지?

  • CoroutineScope
    • 코루틴을 간편하게 사용하고 버리는 개념
  • GlobalScope
    • 싱글톤으로 최상위 레벨에서 코루틴을 실행하는 개념 (비추천)

Coroutine context : 어떤 스레드에서 해당 코루틴을 돌릴지? (디스패처 정하기)

  • Dispatchers
    • Default : CPU 연산을 많이 사용하는 작업
    • IO : 파일 IO, Network IO
    • Main : UI Thread(Main Thread)
    • Unconfined : 일반적인 용도로 사용하지 않는다. (비추천)
  • Job & Deferred
    • Deffered : 결과 값을 갖는 Job
    • Job : 결과 값을 갖지 않는 Job
    • 코루틴이라는 어떤 추상적인 흐름을 Job 이라는 Object 로 만들어서 사용한다.
    • 코루틴 한 덩어리를 Job 한 덩어리라 생각하면 되고, 취소, 예외처리로 흐름제어를 할 수 있다.
    • States
      • New
      • Active
      • Completing
      • Cancelling
      • Cancelled
      • Compeleted
    •  methods
      • cancel
      • join
      • start

Coroutine Builder : 해당 작업을 수행하고 값을 리턴을 할지? 말지?

  • launch
    • Job 객체 반환
    • 코루틴 작업이 실행이되면, 작업이 끝나면 끝.
  • async
    • Deferred 객체 반환
    • 코루틴 작업이 실행되면, 반환된 값이 존재. 그것을 Deferred 타입 형태로 값이 반환 됨
  • runBlocking
    • 사용 x
    • main Thread 를 블럭을 한 뒤에 runBlocking 안에서 작업이 실행된다. 이 안에서 코루틴을 실행할 수가 있다. 이것은 테스트용도로 사용하지만 실제로는 사용하지말라고 한다.
  • withContext
    • 디스패치를 전환시키는 기능을 가지고 있다.
    • Dispatcher.main 에서 처리를 하다보면 IO 에 관련된 일을 처리할 일이 생길 경우, 코루틴에서는 메인을 정의를 했다면 withContext 를 사용해서 필요한 작업만 수행한 다음에 다시 메인으로 돌아가게끔 한다.
    • 이렇게 할 경우 오버헤드가 훨씬적게 관리를 할 수가 있다.
  • 코루틴 지연
    • delay : 정해진 시간동안 코루틴 처리가 중단된다. 또한 멈추는 게 아니라 숫자를 세면서 기다린다는 표현이 맞다.(ex. thread sleep 같은 넉김? 하지만 스레드는 아니다)
    • join : launch 로 실행한 코루틴에 대해서는 조인(join)으로 잡(job)이 실행이 끝날 때까지 기다릴 수 있다.
    • await async 로 실행한 코루틴에 대해서는 어웨이트(awit)로 디퍼드(Deferred)이 실행이 끝날 때까지 기다릴 수 있다.
  • 코루틴 취소 (Cancelling State 로 만든다)
    • cancel : Cancelling 상태로 만든다.
    • cancelAndJoin : Completing → Cancelling → Cancelled
    • withTimeout : 네트워크를 다운로드를 하는 작업이 1000ms 라고 하면, 이 시간이 넘을 경우는 취소하고 익셉션을 넘길 때 사용하는 용도
    • withTimeoutOrNull : 위와 같지만, null 을 반환하게 된다.
  • 코루틴 예외란?
    • CoroutineExceptionHandler 를 이용하여 코루틴 내부의 기본 try catch block 으로 사용할 수 있다.
    • launch, actor : exception 발생 시 바로 예외가 발생.
    • async, produce : 중간에 exception 이 발생해도 하던 처리를 다 끝내고 await 를 만나야 발생
    • Job.cancel() 을 제외한 다른 exception 이 발생하면 부모의 코루틴까지 모두 취소시킴 이는 structured concurrency 를 유지하기 위함으로 CoroutineExceptionHandler 를 설정해도 막을 수 없다.
    • 여러 개의 exception 이 발생하면 가장 먼저 발생한 exception 이 handler 로 전달되며 나머지는 무시된다.
  • 코루틴 정리
    • 코루틴은 스레드가 아니라, 메모리를 줄일 수 있는 모듈이라고 생각함.
    • 코틀린에서 코루틴을 사용하기 위해선 코루틴 스코프, 컨택스트, 빌더를 사용하여 객체를 만들어야 함.
    • CPU 연산 작업이 많다면? Dispatcher.Default 를 사용하면 됨.
    • 코루틴을 처리할 때, 결과값이 필요없다면 launch, 값이 필요하다면 async

Job States cycle

 

이어서, 코루틴을 왜 구글에서 권장을 하는지?

추천하는 사용법, 사용하는 방법을 적은 블로그입니다.

 

https://devnuts.tistory.com/184 

 

[안드로이드] - coroutine (코루틴) - 1

코루틴 코루틴은 루틴의 일종이다. co + routine 으로 협동하는 루틴이라고 한다. 코루틴은 이전에 자신의 실행이 마지막으로 중단되었던 지점에 그 다음 장소에서 실행을 재개한다. 진입점과 출구

devnuts.tistory.com