루틴
프로그래밍에서 루틴이란 프로그램의 흐름을 추상적으로 일컫는 말입니다.
메인루틴과 서브루틴으로 나눌 수 있습니다.
main 함수에 의해 수행되는 프로그램이 있다고 가정하면,
메인 루틴 : main 함수에 의해 수행되는 프로그램의 흐름
서브 루틴 : main 함수 안에서 실행되는 개별 함수들에 의해 수행되어야 하는 흐름
코루틴
실행의 지연과 재개를 허용함으로써, 비선점적 멀티태스킹을 위한 서브 루틴을 일반화한 컴퓨터 프로그램 구성요소
안드로이드에서는 AsyncTask를 이용해서 손쉽게 비동기 프로그래밍을 구현했었지만 구글은 컨택스트 누수, 콜백 누락, 구성 변경 시 충돌 과 같은 여러가지 문제로 API 30 이상부터 deprecate 시키고 코루틴을 사용하도록 권장하고 있습니다.
코루틴과 스레드
구글에서는 AsyncTask를 코루틴으로 대체하여 쓰라고 하고 있기 때문에 얼핏 생각하면 코루틴은 AsyncTask의 약점인 메모리 누수가 없는 스레드라고 생각하기 쉽지만, 코루틴은 스레드가 아닙니다.
메모리 구조의 차이
프로세스 속에서 실행되는 독립된 여러 흐름 중 하나를 스레드라고 합니다. 프로세스는 자기가 사용할 메모리영역인 힙(Heap) 영역을 할당받게 되는데, 이때 스레드는 그 안에서 다시 자신만이 사용할 수 있는 고유의 메모리영역 스택(Stack) 영역 을 할당 받게 됩니다.
하지만 코루틴은 스택을 할당받지 않고 프로세스의 힙 메모리를 공유하여 비동기 작업을 구현한다는 점에서 스레드와 동일한 일을 하고 있지만, 스레드보다는 함수에 가까운 구조를 갖고 있다고 할 수 있습니다.
비동기 작업을 처리할 때 여러 스레드를 돌리게 되면 그만큼의 스택메모리 영역을 새롭게 할당해 주어야 하지만 코루틴을 사용하게 되면 프로세스의 힙 메모리 영역을 사용하기 때문에 새롭게 스택을 할당할 필요가 없어져 사용되는 메모리가 줄어들게 됩니다.
메모리 구조에 대한 이전 발행글
2024.11.11 - [개발지식] - 메모리 구조, 힙(Heap) 영역과 스택(Stack) 영역의 차이
메모리 구조, 힙(Heap) 영역과 스택(Stack) 영역의 차이
메모리 구조프로그램이 실행되면 메모리에 로드 되게 됩니다. 이때 프로그램에서 사용되는 변수들을 저장할 메모리도 필요한데, 이때 컴퓨터의 운영체제는 프로그램의 실행을 위해 다양한 메
goharry.tistory.com
스레드에 대한 이전 발행글
2024.05.08 - [개발지식] - [개발지식] 스레드(Thread), 싱글 스레드(Single Thread), 멀티 스레드(Multi Thread)
[개발지식] 스레드(Thread), 싱글 스레드(Single Thread), 멀티 스레드(Multi Thread)
코드와 함께 싱글스레드와 멀티스레드에 대해서 포스팅해보겠습니다. 1. 스레드란?하나의 프로세스 내부에서 독립적으로 실행되는 하나의 작업 단위라고 할 수 있다.싱글 스레드말 그대로 싱
goharry.tistory.com
수행방식의 차이
비선점형 멀티태스킹 : 코루틴
CPU를 시간분할하여 사용하기 때문에 실제로는 복수의 작업을 동시에 처리 불할 수 없지만 전환속도가 빠르기 때문에 외부에서 볼때는 마치 동시에 처리되는 것처럼 인식 > (동시성)
선점형 멀티태스킹 : 스레드
멀티코어를 사용하면서 동시에 복수의 스레드를 처리할 수 있음 (병행성)
코루틴의 장점
1. 비선점적 멀티태스킹
코루틴이 suspend 함수나 delay 메서드를 만나 일시 정지되면서 다른 작업들에게 실행 기회를 양보하는 것을 의미합니다. 협력형 멀티태스킹은 이렇게 자발적으로 제어권을 넘기면서 여러 작업이 협력하여 CPU 자원을 나눠쓰는 방식입니다.
저는 처음에 suspend로 코루틴을 일시정지 시키는데 어떻게 코루틴을 통해서 비동기 처리를 하지? 라고 생각을 했었습니다.
그래서 제가 이해못했던 부분을 좀 더 길게 풀어서 정리를 하고 넘어가려고 합니다. 네트워크 요청으로 예를 들어보겠습니다.
네트워크 요청 시의 메모리와 스레드 관리 흐름
- 요청을 보낼 때 코루틴 일시 정지
- suspend 함수로 네트워크 요청을 시작하면, 코루틴은 요청 응답을 기다리기 위해 일시 정지 상태로 전환됩니다.
- 이 상태에서 코루틴이 스레드를 점유하지 않으므로, 메인 스레드나 다른 코루틴이 CPU 자원을 자유롭게 사용합니다.
- 백그라운드에서 네트워크 요청 진행
- 네트워크 요청은 비동기 I/O 작업으로, 네트워크 응답이 도착할 때까지 메모리에서 작업이 백그라운드로 진행됩니다.
- 이 작업은 OS 레벨에서 효율적으로 관리되며, 필요한 경우 다른 I/O 스레드나 네트워크 스레드가 이를 처리합니다.
- 응답 도착 시 코루틴 재개
- 네트워크 응답이 도착하면, 코루틴이 일시 정지 상태에서 깨어나 요청 결과를 처리할 준비를 합니다.
- 이때 메모리에 필요한 네트워크 데이터가 로드되고, 코루틴이 다시 활성화되어 나머지 코드를 실행합니다.
- 작업 완료 후 코루틴 종료
- 모든 작업을 마치면 해당 코루틴은 더 이상 필요하지 않으므로 메모리에서 제거됩니다.
이렇게 좀 살짝은 이해를 할 수 있을 것 같습니다.
2. 동시성 프로그래밍 지원
- 한 개의 스레드 안에서 여러개의 코루틴이 돌아가게 만들 수 있어 스레드를 불필요하게 많이 만들 필요가 없고, 그로인해 스레드 끼리 처리 순서를 조정할 때 메모리를 공유하지 않기 때문에 context switching을 하지 않게 되면서 작업 전환시 오버헤드도 줄어들게 됩니다. (오버헤드 : 어떤 처리를 하기 위해 들어가는 처리 시간, 비용, 메모리 등을 말함)
- 코루틴에서 메인스레드를 차단하지 않으면서 현재 코루틴 실행을 일시중지할 수 있는 기능을 제공하기에 경량 쓰레드 라고도 한다.
3. 쉽고 가독성 있게 작성할 수 있는 비동기 처리
- 비동기 코드 작성 시 정상적인 비동기 결과를 받아서 처리하는 코드 외에 비정상적으로 완료되지 못하는 케이스를 예외 처리할 수 있는 부수적인 코드 작성이 필요하지만 코루틴은 예측 가능한 프로그래밍을 할 수 있다는 점에서 동기 코드 진행 흐름과 동일하게 예외처리가 가능해 디버깅 측면에서 큰 장점
- 콜백 지옥을 피할 수 있기 때문에 코드의 흐름 파악이 쉽다.
이번글은 코루틴의 기본적인 개념에 대해서 이해해 보는 글이었습니다.
제가 주로 MVVM 패턴으로 개발을 할 때 viewModelScope를 사용했던 것과 더불어 다른 스코프들에서도 적을 예정이고, 전반적인 코루틴의 구성요소들을 좀 알아볼 예정입니다.
그리고 어떻게 실제로 동작하는지까지 같이 적어보면 좋을 것 같습니다.
비동기 글이기때문에 안드로이드 비동기 관련해서 핸들러라는 친구가 있습니다.
이것도 한번 같이 보시는 것도 추천드리겠습니다.
2024.05.09 - [안드로이드] - [Android] 핸들러(Handler)
[Android] 핸들러(Handler)
안드로이드의 스레드는 두 가지가 존재합니다. 먼저, 일반적인 코드처리, 화면을 갱신하는 처리 등을 담당하는 메인스레드(UI 스레드)스레드 클래스를 사용해서 백그라운드에서 작업을 처리하
goharry.tistory.com
2024.07.13 - [안드로이드] - [Android] Handler 예제
[Android] Handler 예제
핸들러에 대해 설명한 글을 보고 오시면 더 이해하기 좋을 것 같습니다.2024.05.09 - [안드로이드] - [Android] 핸들러(Handler) [Android] 핸들러(Handler)안드로이드의 스레드는 두 가지가 존재합니다. 먼저
goharry.tistory.com
쓰고싶은 글들이 너무 많은데 쉽지 않네요 ㅎㅎㅎ
끝!
'안드로이드' 카테고리의 다른 글
[Android] 패키지 이름 (2) | 2024.12.30 |
---|---|
[Gradle] 버전 카탈로그 (0) | 2024.12.20 |
[Android] Application Not Responding (ANR) (2) | 2024.11.12 |
[Android] 안드로이드 앱으로 아두이노 제어하기 (USB 시리얼 통신) (7) | 2024.11.10 |
[Android] Fragment Lifecycle (1) | 2024.11.09 |