4 분 소요

  • 안드로이드 앱은 UI 스레드가 너무 오랫동안 차단되면 ‘ANR(애플리케이션 응답 없음)’ 오류가 발생하게 된다❗
  • 앱에서 개발을 하다보면 비동기 백그라운드 작업 을 통하여 이러한 ANR이 발생하지 않도록 노력을 해야한다.

처음으로 앱을 개발할때 네트워크 통신을 할때 위와 같은 문제에 봉착하여 큰 난관에 빠졌었던 기억이 많다. 이번 포스팅을 시작으로 비동기 작업 을 공부하며 정리해 보려고 한다🤔

📍 잠깐 짚고 넘어가기

동기(synchronous : 동시에 일어나는) : 요청을 보내면 결과값이 오기까지 작업을 멈춘다.
비동기(Asynchronous : 동시에 일어나지 않는) : 요청을 보내면 작업을 멈추지 않고 다른 일을 수행한다.


Thread 개요

스레드는 멀티태스킹 운영체제의 초석으로 메인 프로세스 내 에서 작은 프로세스가 실행 되는 것으로 생각할 수 있다.

📍스레드의 목적은 앱 내부에서 병렬로 실행될 수 있는 코드 를 만드는 것

🤔알아보고 가기

Process vs Thread

프로세스와 비슷해보이는 스레드를 알아보기전에 ~ 프로그램이라는 말을 많이 들어봤을 것이다.
프로그램의 예시는 흔히 위도우 컴퓨터에서 볼 수 있는 .exe 파일이라고 생각하면 된다.

📍Program : 보조기억장치에 존재하는 실행파일

이러한 프로그램은 사용자가 클릭을 하여 운영체제가 실행을 하게 해야한다. 즉 실행되고 있는 프로그램이 프로세스 라고 할 수 있다.

📍Process : 메모리에 올라와 실행되고 있는 프로그램 의 인스턴스

🔔프로세스는 다음과 같은 특징이 있다.

  • 프로세스는 하나 이상의 스레드(메인 스레드)를 포함한다.
  • 각 프로세스는 별도의 주소 공간에서 실행되며, 한 프로세스는 다른 프로세스의 변수나 자료구조에 접근할 수 없다.
  • 다른 프로세스의 자원에 접근을 하려면 프로세스간 통신(IPC: Inter-Process-Communication)을 사용해야 한다.
  • 프로세스는 각각 Code, Data, Stack, Heap의 구조 로 되어있는 독립된 메모리 영역 을 할당 받는다.

그렇다면 하나의 예시로 크롬창(하나의 프로세스)으로 웹 서핑을 하고 있다고 생각해 보자. 사용자들은 백그라운드로 게임을 다운하면서 웹 서핑을 계속 하고싶을 것이다. 이러한 하나의 프로세스에서 더 작인 실행 단위 를 여러 스레드 를 통하여 실행하게 된다.

📍Thread : 독립적인 메모리공간(Stack)을 가지는 프로세스 내에서 실행되는 여러 흐름 단위

🔔스레드는 다음과 같은 특징이 있다.

  • 하나의 스레드는 독립적인 메모리공간(Stack) 을 할당 받고 프로세스의 Code, Data, Heap 영역은 공유한다.
  • 각 스레드는 Stack 메모리를 공유할 수 없다.

동시성 vs 병렬성

Thread와 코루틴은 모두 동시성 프로그래밍 을 위한 기술이다.

동시성 (Concurrency)

동시성 프로그래밍은 여러 작업을 동시에 실행 하는 것이다. 말은 동시에 실행이라고 하였지만 이는 작업들을 잘게 쪼게어 빠르게 번갈아가며 수행 하여 두 작업은 동시에 실행되는 것 처럼 느껴지게 하는 것이다.

병렬성 (Parallelism)

병렬성 프로그래밍은 말 그대로 여러 작업을 한 번에 동시에 실행 하는 것이다. 즉 병렬성은 실행시키는 자원(CPU 코어)이 여러개(멀티코어)일때 가능한 방법이다.

Thread vs Coroutine

Thread와 Coroutine은 둘다 동시성을 보장 하기 위해 사용된다. 처음 코루틴에 대한 용어를 알게되어 찾아봤을때는 스레드와 별반 차이를 몰랐었다. 스레드와 코루틴의 개념을 알아보면서 둘의 차이점을 알아보았다.

Thread

  • 작업의 단위 -> Thread
    • Thread는 독립적인 메모리공간(Stack)을 가진다
  • 동시성 보장 수단: Context Switching
    • OS 커널에 의한 Context Switching 을 사용한다.
    • 블로킹 : (Thread 1) 이 (Thread 2) 의 결과가 나오기까지 기다려야한다면 (Thread 1)은 블로킹 되어 그 시간동안 해당 자원을 사용하지 못한다.

🤔Context Switching?

  • CPU에서 여러 프로세스를 번갈아 가면서 작업을 처리하는 데 이 과정을 Context Switching라 한다.
  • 구체적으로, 동작중인 프로세스가 대기 할때 해당 프로세스의 정보(Context)를 보관하고 있다가 다음 순서의 프로세스가 동작할때 해당 정보(Context)를 통하여 상태를 복구하는 작업을 말한다.

위의 그림을 보면 작업 단위는 모두 Thread인것을 볼 수 있다. 위의 그림에서 동시성이 보장 이 되는 과정을 보자.

  • Thread A 에서 작업 1을 수행중에 작업 2가 필요할때 이를 비동기로 호출 하게 된다.
  • 이 때 Thread A 는 작업을 멈추고(블로킹) 되고, Thread B 로 Context Switching 이 일어나 작업 2 를 수행한다.
  • 작업 2가 완료되면 해당 결과값을 Thread A 로 Context Switching 이 일어나 작업 1에 반환하게 되고, 동시에 수행할 작업 3과 작업 4는 각각 Thread C 와 Thread D 에 할당된다.
  • OS 커널에서는 Preempting Scheduling 을 통하여 각 작업에 대해 얼만큼 수행할지 또는 어떤 작업을 먼저 수행할지를 결정 하여 그에 맞게 동작을 하게 하여 동시성을 보장 하게 되는 것이다.

Coroutine

  • 작업의 단위 -> Object(Coroutine)
    • 여러 작업에 각각 Object 를 할당한다.
    • Coroutine Object 는 객체를 담는 JVM Heap 에 적재됩니다.
  • 동시성 보장 수단: Programmer Switching = No Context Switching
    • 프로그래머의 코딩 을 통해 Switching 시점을 마음대로 정한다.
    • Suspend (Non-Blocking): Object 1(작업 1)Object 2(작업 2)결과가 나오기까지 기다려야한다Object 1(작업 1)Suspend(중지) 되지만 Object 1(작업 1)를 수행하던 Thread 는 그대로 유효 하기 때문에 Object 2(작업 2)Object 1(작업 1)동일한 Thread 에서 실행 될 수 있다.

작업의 단위는 Coroutine Object 이므로 작업 1 수행중에 비동기 작업 2가 발생하더라도 작업 1을 수행하던 같은 Thread에서 작업 2를 수행할 수 있으며, 하나의 Thread 에서 여러개의 Coroutine Object 들을 수행할 수도 있다.

위의 그림에서 작업 1에서 작업 2의 전환에 있어서 Thread A 위에서 Coroutine Object 객체들만 교체 만 이뤄지기 때문에 Context Switching 은 필요가 없다.
Coroutine은 한 Thread 에 다수의 작업(Objcet) 을 수행할 수 있음과 Context Switching 이 필요없기 때문에 Lightweight Thread 라고도 불린다.

다만 위의 세번째 그림에서 처럼 작업 3, 작업 4를 위해 Thread C가 동시에 실행이 된다면, 동시성을 보장 하기 위하여 Context Switching이 필요하다. 따라서 Coroutine의 No Context Switching 이라는 장점 을 최대한 활용하기 위해 여러 Thread 를 사용하는 것보다 단일 Thread 에서 여러 Coroutine Object 들을 실행하는 것 이 좋다😮

💡Coroutine 은 Thread 의 대안이 아니라 기존의 Thread더 잘게 쪼개어 사용 하기위한 개념이다.

  • 작업의 단위가 Thread가 아닌 Object 단위로 축소하면서 단일 Thread가 여러 코루틴을 다룰 수 있기 때문 에 작업의 수만큼 Thread를 생성하지 않아도 되어 메모리 낭비, Context Switching 의 비용 낭비를 할 필요가 없다.

마무리 정리

처음 Coroutine의 용어를 접했을 때는 Thread와의 차이를 알지 못하고 같은 작업을 한다고 생각하였었다😂

앱 개발에서 비동기 작업(DB 트랜잭션, 네트워킹 요청등)은 거의 필수적으로 사용한다고 생각한다. 이러한 비동기 작업 은 앞서 정리한 내용과 같이 Coroutine을 활용 하여 비용절감을 할 수 있기 때문에 안드로이드 공부를 꾸준히 해가면서 많이 접하고 적극적으로 사용해봐야겠다👍


References

태그:

카테고리:

업데이트:

맨 위로 이동 ↑

댓글남기기