Language/Kotlin

[Coroutine] 코루틴이란?

개랭갱깽스타 2022. 2. 3. 17:20

0.  큰 그림

큰 그림의 개념 부분을 이번 포스팅으로 작성하겠습니다~

 

1. 코루틴, Coroutine

비선점형 멀티태스킹(non-preemptive multitasking) 을 수행하는 일반화한 서브루틴

즉, 서로 협력해서 실행을 주고받으면서 작동하는 여러 서브 루틴이다.

🙉   멀티태스킹/ 비선점형 멀티태스킹 / 선점형 멀티태스킹 이란?

더보기

먼저, 멀티태스킹 이란?

여러 작업을 동시에 수행하는 것처럼 보인다. or 실제로 동시에 수행한다.

비선점형 멀티태스킹

  • CPU를 차지하고 있는 쓰레드가 CPU 연산이 필요 없음을 나타냈을 때만 운영체제가 이를 중단시킬 수 있다.
  • 강제로 죽이려면, 리셋해야 한다.
  • 각 참여자들이 서로 자발적으로 협력해야 한다.

선점형 멀티태스킹

  • CPU를 차지하고 있는 쓰레드를 운영체제가 강제로 중단시킬 수 있다.

🙉  서브루틴 이란?

더보기
  • 여러 명령어를 모아 이름을 부여해서 반복 호출할 수 있게 정의한 프로그램 구성요소
  • Ex. 함수, 메소드
  • 진입: only one
    • 서브 루틴의 맨 처음부터 실행 → 활성 레코드(activation record) 가 스택에 할당 → 서브 루틴 내부의 로컬 변수 등의 초기화
  • 실행 중단: return or 함수 끝 → 중단 지점이 여러 개 있을 수 있다!
    • 제어를 호출한 쪽에게 돌려 준다. → 활성 레코드가 스택에서 사라진다.
    • 서브루틴을 여러 번 반복 실행해도 항상 같은 결과를 반복해서 얻게 된다. (전역변수나 다른 부수 효과가 없을 경우)
    • HOW?→ 서브 루틴이 호출될 때마다 저장된 메모리로 이동했다가 return 을 통해 원래 호출자의 위치로 돌아오게 된다.
    • 별도의 메모리에 해당 기능을 모아 놓고 있어 → 서브 루틴이 호출될 때마다 저장된 메모리로 이동했다가 return 을 통해 원래 호출자의 위치로 돌아오게 된다.

참고. https://foxtrotin.tistory.com/262

 

2. 그래서... 코루틴은 Thread 랑 어떻게 다르다는 거지?

🙉   먼저, 프로세스 / 스레드 란?

더보기
  • Process프로그램 이 메모리에 적재되어 실행되는 인스턴스 
  • Thread: Process 내 실행되는 여러 흐름 단위
Process 와 Thread 의 메모리 구조

 

프로그램이 실행되면, Process 가 생성되면서 Heap 영역과 하나의 Thread, 하나의 Stack 영역을 갖게 된다.   Thread 가 추가 될때마다 그 수만큼 Stack 이 추가된다.

 

결론부터 말하자면, Thread 와 코루틴은 작업의 단위가 다르다.

Thread는 작업의 단위가 Thread!

코루틴은 작업의 단위가 Thread 안의 작은 Thread 처럼 동작하는 코루틴(Object)!

 

, 코루틴은 Thread 안에서 실행되는 일시중단 가능한 작업의 단위

(= Thread 하나를 일시중단 가능한 다중 경량 Thread 처럼 사용하는 것)

쓰레드와 코루틴

 

🙉  흠.. Process 내 실행 흐름의 단위는 Thread 라고 배웠는데.. 코루틴은 어떻게 작업 단위로 가능한거지?

더보기
  • Thread: 자신만이 사용할 수 있는 고유의 Stack 을 할당받는다.
  • 코루틴: Process의 Heap 메모리를 공유하여 사용한다. (함수에 가까운 구조) - Stack 할당 X

더 자세한 내용은 여기를 참고해주세요!  https://cliearl.github.io/posts/android/coroutine-principle/

 

3. 그럼 코루틴은 어떤 게 좋을까?

  • 각 스레드마다 갖는 Stack 메모리 영역을 갖지 않기 때문에  

→ 스레드 사용시 스레드 개수만큼 Stack 메모리에 따른 메모리 사용공간이 증가하지 않아도 된다.

 

  • 코루틴은 Heap 메모리를 공유하여 사용하기 때문에

→ 같은 프로세스내에 ‘공유 데이터 구조’(Heap)에 대한 Locking 걱정이 없다.

 

  • Thread 를 만드는 데 비용이 크다(Context Switching).  코루틴은 Thread 를 새로 생성하지 않기 때문에  

→ 작업 전환 시의 오버헤드가 줄어든다.

 

자원 낭비 측면에서 얼마나 효율적인 지, 좀 더 직관적으로 이해하기 위해, 예시를 봐 볼까요~?

상황: 작업1 에서 작업 2의 결과가 필요한 경우

 

Thread

Thread1에서 작업1 수행, Thread2 에서 작업2 수행

  • Thread1 에서 작업1을 수행하고,
  • Thread2 에서 작업2를 수행한다.

Thread1 은 Thread2의 작업이 끝날 때 까지 기다려야 한다.(Blocking)

, Thread1은 그동안 놀게!!! 된다. → 이것은, 바로 자.원.낭.비.

 

코루틴

Thread1에서 작업1(코루틴1), 작업3(코루틴2) 수행, Thread2에서 작업2수행

  • Thread1 에서 작업1과 작업3 수행, (Thread1 에서 작업 2개를 수행 할 수 있는 이유는? 코루틴이기 때문!)
  • Thread2 에서 작업2를 수행한다.

Thread1 의 작업1 이 Thread2 의 작업2 결과를 기다리는 동안, Thread1 는 작업3 을 수행하면 된다!

, Thread1의 자원을 최대한 사용할 수 있다.

 

그렇다면, 이번에는 작업 전환 시 오버헤드가 얼마나 줄어드는 지,

Context Switching 횟수를 눈으로 비교 할 수 있는 예제를 봐볼까요~?

상황: 작업1 에서 작업 2의 결과가 필요하고 && 작업3, 작업4 진행도 필요한 경우

Thread

Thread 를 사용한 작업 수행

  • Thread1(A) 에서 작업1 수행
  • Thread2(B) 에서 작업2 수행
  • Thread3(C) 에서 작업3 수행
  • Thread4(D) 에서 작업4 수행

작업1 에서는 작업2의 결과값이 필요하므로, 두번째 그림에서 작업2가 수행되는 동안, Thread1(A) 는 Blocking 된다.

그 후, 작업2 의 결과값이 나오면,  Thread1(A) 의 작업1, Thread3(C) 의  작업3, Thread4(D) 의 작업4 수행된다.

 

이 때, Context Switching 은 얼마나 일어날까? (싱글 코어 CPU 기준)

Thread 의 Context Switching

Thread1(A) 에서 작업1 수행 → Thread2(B) 에서 작업2 수행 → [ Thread1(A) 에서 작업1 수행  → Thread3(C) 에서 작업3 수행  → Thread4(D) 의 작업4 수행 ] * 반복

 

코루틴

코루틴을 사용한 작업 수행

  • Thread1(A) 에서 작업1, 작업2 수행
  • Thread3(C) 에서 작업3, 작업4 수행

작업1 에서는 작업2의 결과값이 필요하므로, 두번째 그림에서 작업2가 수행되는 동안, 작업1 Suspending 된다. 그러나, Thread1 자체는 Blocking 되지 않는다.

그 후, 작업2 의 결과값이 나오면,  Thread1(A) 의 작업1, Thread3(C) 의  작업3, 작업4 가 수행된다.

 

이 때, Context Switching 은 얼마나 일어날까? (싱글 코어 CPU 기준)

코루틴의 ContextSwitch

[ Thread1(A) 에서 작업1 수행  → Thread3(C) 에서 작업3, 작업4 수행 ] * 반복

작업1 작업2, 작업3작업4 의 Thread 가 같기 때문에 작업 전환 시에 Context Switching 이 필요 없다.

 

Thread 와 코루틴의 ContextSwitch 횟수 차이

Thread 와 코루틴의 ContextSwitch 횟수 차이

 

그래서... 어쨌거나 결론은!

Thread는 Thread,
코루틴은 코루틴 !

 

 

나중에는 코루틴 보다 작은... 코루틴처럼 동작하는 게 나올...까?ㅎㅎ

 

.참고

https://cliearl.github.io/posts/android/coroutine-principle/

 

알기쉬운 코루틴 이론

이번 포스팅에서는 코틀린의 코루틴(Coroutine)에 대해 알아보도록 하겠습니다. 코루틴의 개념 안드로이드에서는 AsyncTask를 이용해서 손쉽게 비동기 프로그래밍을 구현했었지만 구글이 다음과 같

cliearl.github.io

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

 

Coroutine, Thread 와의 차이와 그 특징

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

aaronryu.github.io

 

반응형