코틀린 Coroutines에 관한 서적이며 버전이 1.3.6에 맞춰 작성되어 변경 부분은 하기에 따로 기술 하였다.
이에 따라 변경분은 저서와 다르게 본문을 재 작성하였다
-
동시성과 병렬성
- 동시성: 두 개 이상의 알고리즘의 실행 시간이 겹칠 때 발생
- 단일 코어에서 멀티 스레드를 이용한 실제 작업은 컨텍스트 스위칭이 일어난다
- 코드의 준 독립적인 부분이 완성되는 순서에 관계 없이 전체 결과는 결정적이어야 함
- 병렬성: 두 개 이상의 알고리즘이 정확히 같은 시점에 실행 될 때 발생. 병렬성은 동시성을 수반한다
- 동시성의 어려움
- 레이스 컨디션 발생: 동시성 코드가 항상 특정한 순서로 실행되리라 가정 할 때 발생
- 원자성 위반: 데이터 손실이 발생 할 수 있다
- 교착 상태: 두 작업이 서로 작업이 서로 끝나기를 기다리기 때문에 종료되지 않음
- 라이브 락: 어플리케이션이 동작은 하지만 정상적으로 동작하지 않는 상황이 지속됨
-
코루틴의 내부 구조
- CPS( Continuation Passing Style ) : 호출되는 함수에 연속체(Continuation)를 보내는 것을 전제로 함수가 완료되는 대로 연속체를 호출하는 코딩 스타일
- 실제 코루틴은 CPS 로 변환되어 수행된다.
- 컴파일 과정에서 Suspend 연산은 상태 머신 형태의 코딩으로 변경된다.
- 연속체( Continuation )
- 호출되는 컨텍스트에 대한 정보를 담고 있는 콜백
- 이전 실행된 연속체의 마지막 값을 입력으로 받는다
- 실제 스레드의 변경은 Dispatcher에서 일어난다
- 전체 코루틴 동작은 파이프라인 패턴을 이용하여 수행된다.
-
코루틴 디스패처(dispatcher)
- 코루틴을 시작하거나 재개할 스레드를 결정하는 역할
즉시 비동기 실행이 필요한 경우: CoroutineScope(Dispatchers.IO).launch
- 기본 디스패처 종류
- Defult: 상위 디스패처가 있다면 사용하며 그 외에는 공유된 스레드 풀 사용
- IO: 공유된 스레드 풀을 사용
- Main: 대부분 싱글 스레드인 메인 스레드에서 실행
- Unconfined: 가용한 아무데서나 돌림
-
코루틴 빌더
- suspend 람다(또는 함수)를 받아 코루틴을 생성하는 역할
- 종류
- Deferred(함수명: async)
- 결과(반환값)가 예상되는 코루틴을 위해 사용한다.
- 사용하는 범위를 작게 만드는 것이 좋다 → 특정 구현에 묶이는 문제를 줄임
- 예외는 하기 두 종류의 결과 대기 함수에 따라 다르게 처리된다
- join: 예외를 전파하지 않는다
- await: 예외를 전파한다
- Job(함수명: launch): 결과를 반환하지 않는 코루틴을 위해 사용한다. 예외를 전파하지 않는다
- runBlocking: 코루틴을 블록킹 코드 블록과 연결하기 위해 사용된다.
- 이 빌더를 사용하게 되면 스레드를 블록킹 한다
- 예외를 전파한다
-
코루틴 컨텍스트
- 코루틴이 어떻게 실행하고 동작하는지 정의할 수 있게 해주는 요소의 그룹
- 디스패처, ExceptionHandler 와 조합을 통해 생성된다
- withContext 함수를 통해 코루틴 빌더 내부에서 다른 컨텍스트로 변경이 용이하다
-
코루틴 이터레이터, 시퀀스, 프로듀서
- 이터레이터
- 한 번만 읽기 가능하며 이전 방향으로 돌아갈 수 없다
- 상태가 저장되어 남은 값만을 읽어들이기가 가능하다 ( forEachRemaining 함수 사용 )
- 시퀀스
- 인덱스로 특정 값을 읽기 가능하다
- 상태가 저장되지 않아 사용(종단 연산 적용) 후 초기화 된다
- 프로듀서
- 실행 중에 일시중단 할 수 없는 이터레이터, 시퀀스와 달리 중단 가능하다
- 채널(하기 기술)을 사용하므로 수신하면 데이터가 삭제된다
-
채널 ( Channel And Flow )
- 동시성의 많은 오류는 메모리를 공유하기 때문에 발생
- 이를 해결하기 위해 스레드가 상태를 공유하는 대신 메시지를 주고 받는 통신을 이용
- Producer(생산자 코루틴)과 Consumer(소비자 코루틴) 을 이어주는 가교
- BackPressure(역압) 지원
- 종류
- 언 버퍼드 채널: 생산자는 데이터가 소비 될 때까지 신규 데이터를 생산할 수 없다
- 버퍼드 채널
- LinkedList Type: 중단 없이 무한(메모리 한계)까지 전송 가능하다
- Array Type: 지정한 버퍼 크기까지 생산 가능하다
- Conflated Type: 새로운 데이터가 들어오면 이전 데이터를 버린다
-
스레드 한정, 액터, 뮤텍스
- 동시성 오류 중 원자성 위반 문제를 해결하기 위해 코루틴이 제공하는 3가지 방법
- 스레드 한정: 공유 상태에 접근하는 모든 코루틴 디스패처를 단일 스레드로 한정하는 방법
- 액터 스코프: 스레드 한정과 더불어 채널을 이용하여 통신 경로를 확장
- 뮤텍스
- 상호 배제(mutual exclusions): 한 번에 하나의 진입자만 코드 블록을 실행할 수 있는 동기화 매커니즘
- 잠금의 한 종류이다
- 버전 별 변경사항
- V 1.4
- New Flow Type 도입
- 시퀀스와 유사하며 일시 중단이 가능
- 상태를 저장하지 않음
- StateFlow(콜드), SharedFlow(웜) 두 종류가 존재함
- V 1.5
- V 1.6
- V 1.7
- V 1.8
- V 1.9
- V 1.10