ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Kotlin] 코틀린 코루틴의 정석 요약
    Software Development/기타 2024. 6. 9. 00:00

    개발 도서를 읽으면서 많은 번역본을 읽을 때 마다 번역에 대한 아쉬움을 느낄 때가 있었습니다.

    '코틀린 코루틴의 정석'을 읽으면서 코루틴의 동자원리에 대해서 잘 이해할 수 있었습니다.

    이번 요약을 통해서 나중에 필요시에 가볍게 꺼내볼 수 있으면 좋겠습니다.

    자세한 내용은 아래의 책에 있습니다.

    http://www.acornpub.co.kr/book/kotlin-coroutines

     

    코틀린 코루틴의 정석

    많은 개발자들이 어렵게 느끼는 비동기 프로그래밍을 다양한 시각적 자료와 설명을 통해 누구나 쉽게 이해할 수 있도록 쓰인 책이다.

    www.acornpub.co.kr

    코루틴의 이점은 성능, 안정성, 가독성에 있다.

    멀티 스레드 프로그래밍 방식은 사용자가 스레드를 기반으로 작업하기 때문에 스레드 블로킹을 극복하기 어려웠다.

    이를 해결하기 위해 가독성을 해치는 콜백 같은 방식이 사용됐다.

    코루틴은 경량 스레드라는 개념을 도입해 간단한 코드만으로도 작업을 구조화해서 관리하여 안정성을 높였다.

     

    스레드 기반 작업의 한계와 코루틴의 등장

    단일 스레드 기반 애플리케이션의 한계

     -> 다른 작업을 동시에 수행하지 못함

    멀티 스레드 프로그래밍을 통한 단일 스레드 한계 극복

     -> 그러나 스레드는 생성 비용이 비쌈(성능에 악영향). 스레드에 관리가 개발자에게 책임이 있음(메모리 누수 발생 가능성)

    이를 해결하기 위해  Executor 프레임웍을 통한 스레드풀 사용

     -> 개발자가 직접 스레드를 관리하지 않아도 됨. 그러나 스레드 블로킹은 막을 수 없음.

    이를 보완하기 위해 CompletableFuture, RxJava가 등장해 결괏값을 데이터 스트림으로 처리함으로써 스레드 블로킹을 방지

     -> 그러나 근본적인 문제가 있음.

    콜백이나 체이닝 함수를 통해서 스레드 블로킹을 피할 수 있지만, 작업 간의 종속성이 복잡해질수록 스레드 블로킹을 피하기가 어렵고 만들어진 스레드가 성능 제대로 발휘하지 못할 수 있다.

    애플리케이션은 작업 간의 종속성이 매우 복잡하고 네트워크 작업을 수없이 수행하므로 스레드 블로킹은 필연이다.

     

    코루틴은 작업 단위 코루틴을 통해 스레드 블로킹 문제를 해결한다.

    스레드에서 작업 실행 도중 일시 중단할 수 있는 작업 단위이다.

    코루틴이 스레드 사용 권한 양보를 통한 블로킹 방지, 적은 생성 비용 경량 스레드라고 불리는 이유다.

    CorountineDispatcher

    스레드로 코루틴을 보내는 주체이다. 코루틴 실행을 관리한다. 자신에게 실행 요청된 코루틴을 작업 대기열에 적재하고, 실행할 수 있으면 스레드로 보낸다.

    코루틴 빌더와 Job

    순차처리가 필요한 경우: join함수 사용

    isActive, isCancelled, isCompeleted으로 코루틴 활성화, 취소, 완료를 알 수 있다.

    Async와 Deferred

    async 함수를 사용하면 결괏값이 있는 코루틴 객체인 Deferred 반환.

    Deferred 객체의 await 함수는 코루틴이 실행 완료될 때까지 호출부의 코루틴을 일시 중단한다는 점에서 Job 객체의 join 함수와 매우 윳하게 동작.

     

    withContext로 async-await 대체 가능.

    withContext는 새로운 코루틴을 만들지 않기 때문에 하나의 코루틴에서 withContext 함수가 여러 번 호출되면 순차적으로 실행된다.

    CoroutineContext

    코루틴을 실행하는 환경을 설정하고 관리하는 인터페이스

    Name, Dispatcher, Job, Handler

    구조화된 동시성

    부모 코루틴은 자식 코루틴에게 실행 환경을 상속한다.

    모든 실행 환경이 상속되진 않는다.

    코루틴의 이해

    서브루틴은 하위에서 실행되는 루틴이다.

    서브루틴은 한 번 실행되면 끝까지 실행되는 반면에 코루틴은 서르 간에 스레드 사용 권한을 양보하며 함께 실행

    delay 함수는 스레드를 양보하고 일정 시간 동안 중지

    join, await의 대상이 된 코루틴이 완료될 때 까지 스레드를 양보하고 일시 중단

    yield 권한을 명시적으로 양보

    코루틴 심화

    코드의 안정성을 높이기 위해 불변 변수를 쓰는게 좋으나, 스레드 간에 데이터를 전달하거나 공유된 자원을 사용하는 경우 가변 변수를 사용해 상태를 공유한다.

    JVM은 스레드마다 스택 영역이라고 불리는 메모리 공간을 갖고, 여기에 원시 타입의 데이터가 저장되거나 힙 영역에 저장된 객체에 대한 참조가 저장된다.

    힙에는 JVM 스레드에서 공통으로 사용되는 메모리 공간으로 객체나 배열 같은 크고 복잡한 데이터가 저장

     

    JVM이 실행되는 컴퓨터의 메모리 구조

    CPU 레지스터, CPU 캐시 메모리, 메인 메모리 영역이 있다.

    하드웨어 메모리 구조는 JVM의 스택 영역과 입 영역을 구분하지 않는다. 

    1. 공유 상태에 대한 메모리 가시성 문제

     -> 하나의 스레드가 캐시 메모리에 카운트를 증가시켜도 다른 스레드는 그 카운트가 증가됐는지 알 수 없다.

     -> @Volatile로 막을 수 있음. 캐시 메모리 안쓰게 할 수 있음.

    2. 공유 상태에 대한 메모리 경쟁 상태 문제

     -> @Volatile해도 메인 메모리에 Race Condition으로 인한 오류 발생 가능 Mutex로 막아야함

     

    댓글

Designed by Tistory.