본문 바로가기

코틀린/코루틴

코루틴이 그래서 정확히 무엇이며 왜좋냐? -2-

코루틴이 무엇이며 코루틴이 왜 좋은지에 대해서 일단 개념적으로 알고 사용법을 익혀야 할것이다.

그리고 코루틴의 개념은 안드로이드나 코틀린을 뛰어넘어서 cs전반적으로 공부를 좀해야 이해가 되고 지금도 완벽히는 이해하지

못한거같다.

cs 좀 중요한듯 이래서 대기업에서는 cs 를 보는건가? 비전공자는 슬프다.~~

그래서 항상 내가 해온방식 이해한내용까지 정리하고 흑마법을 써볼려한다.

데브 경수님 인스타 개꿀잼 쿠쿠루삥뽕

자 여태까지 코루틴을 어떻게 접하게 되었고 어떻게 공부했으며 어떤방식으로 사용했는가?

 

안드로이드 개발자라면 대부분 나와 비슷한 길을 걸어왔으리라 생각한다.

 

구글: 코루틴짱임 rx쓰지마세요 코루틴 쓰세요 츄라이 츄라이

 

나: 아 콜백지옥 진짜 노답이네 이걸 어캐해 내가 컴퓨터야? 이딴걸 어캐봐 근데 rx는 또 개념이 왤케 어려워 데이터가 흐른다고? 흐르긴 뭘 흘러 내침이 흐른다. 코루틴은 구글에서 하라니 일단 해볼까 코루틴은 좀 초반에 익히기 그나마 수월하다던데

 

->막무가내로 사용법을 찾아서 그냥 대충 뷰모델 스코프에 때려넣었더니 비동기 처리가 되네, 동기처리 코드처럼 써도 잘 처리되네 코루틴 짱짱맨 

 

근데 코루틴의 기능과 활용방향은 무궁무진하고 코루틴을 잘모르는 상태에서 함부로 코루틴을 남발하다가 오류한번 터지면 연쇄적으로 다 부모스코프 까지 터져버리는 경험후 아 코루틴은 무서운거구나 하면서 코루틴에 대한 막연한 공포감이 생긴다.

그이후 코루틴만 만나면 바르르르 떨게되는 나를 볼수 있게 된다.

 

이런 막연한 공포감을 없애려면 어떻게해야하는가? -> 자세히 알면된다.

그래서 코루틴이 정확히 무엇인지 비동기처리는 왜 이렇게 마법같이 되는거고 사실상 비동기처리를 단순히 해주는것이 아닌 컴퓨터의 자원 정확히 말하자면 쓰레드의 성능을 높이기 위해 쪼개쓰는 방법임을 알아보자.

 

 


 일단 코루틴이 무엇인가?

그래서 일단 코루틴이 뭔데 코틀린으로만 개발한 난 처음에 Koroutine 인줄 알았다. 

하지만 코루틴은 요즘 나온 신기술도 아닐뿐더러 무슨 새로운 라이브러리라서 어떤 마법같은 일을 벌이는것이 아니라 언어별로 어떻게 사용하느냐의 차이이지 코틀린 혹은 안드로이드 만의 것이 아니다.

 

예를들어  C#,Go,Javascript 등등 많은 언어에서 지원하며

웹할때 공부했던 자바스크립트의 async/await 가 코루틴의 개념이였고 이미 사용해봤던것이였다.

출처:https://wooooooak.github.io/kotlin/2019/08/25/%EC%BD%94%ED%8B%80%EB%A6%B0-%EC%BD%94%EB%A3%A8%ED%8B%B4-%EA%B0%9C%EB%85%90-%EC%9D%B5%ED%9E%88%EA%B8%B0/

 

그래서 결국에 근본적으로 들어가면 코루틴이 무엇인가 단순 비동기 처리만 해주는 건가? 콜백처럼?

아니다!!!! 코루틴은 컴퓨터의 자원을 어떻게 효율적으로 사용하게 해줄지에 대한 아주 근본적인 영역이고 쓰레드를 얼마나 효율적으로 더 쪼개서 사용할수있는 가에 대한 이야기이다.

이에 대한 성능 향상은 개발자가 Thread pool 을 어떻게 지정해주는가에 따라서 쓰레드의 context switching 이 일어나는 횟수를 줄일수있고 이는 성능향상에 직결된다 (이런부분은 글 뒷편에서 더 자세히 살펴볼 예정이다.)-> 즉 결국 우리의 궁극적인 목표는 context switching 이 최대한 덜일어나도록 프로그램을 짤수있는 능력을 길러야한다.

 

어쨋든 성능이 기존에 처리했던 방법들에 비해서 좋아지는건 그래서 알겠고 결론적으로 비동기에 관한건 어떻게 되는데? 라고 생각해보면

기존에 비동기 처리를 위하여 thread, ExecutorServices,Rx,Callback 를 이용했었는데 

결국 rx 이던 ExecutorServices 던 라이브러리에서 어떻게 쓰레드를 열어서 잘사용할수 있는가에 대한 이야기였고.

코루틴 또한 쓰레드를 어떻게 쪼개서 야무지게 사용할 수 있느냐의 이야기이기 때문에 쓰레드를 통해서 했던 동시성 프로그래밍을 통한 일의 분산 을 시켜서 안드로이드에서 ANR을 만나지 않도록 하는 용도로도 쓰일수있는것이다.(비동기처리 쌉가능) 즉 결국 쓰레드 상위호환이다.

 

일단 서론은 여기 까지이고 이미 중요 키워드들이 많이 나왔다 컨텍스트 스위칭, 쓰레드

약간 CS면접 준비 느낌스로 CS공부할때 하는거 아냐? 라는 생각이 든다 -> 맞다 그때하는거다 그래서 따분하지만 코루틴에 대해서 이야기하기전에 프로세스,쓰레드,컨텍스트 스위칭, 그리고 각종 구조에 대해서 아주 간단하게 용어 정리 느낌으로 정리하고 가볼것이다.

 

1.컨텍스트 스위칭

-PCB : 운영체제에서 프로세스에 대한 메타데이터를 저장한 데이터 -> 뭔가 이것저것 구조를 가지고있는 데이터 묶음이다. 

한마디로 프로세스를 실행하기위해서 뭐 여타 저장해야할 주소값(프로세스 아이디 같은거) 등등을 저장해 놓은 데이터 덩어리이다. 프로세스가 실행될때 생성된다.

 

-컨텍스트 스위칭

CPU내에 존재하는 레지스터에 PCB를 교환하는 과정이다. 즉 스케쥴링에 의해 기존에 실행되던 프로세스의 PCB 내용들을 어딘가에다 저장해주고(추후에 이어서 실행하기위해) 그리고 새로 실행되는 프로세스가 아니라면 어딘가에 저장해놓은 PCB를 가져와서 레지스터에다가 올리는 것이다. 아무래도 기존의 데이터를 들어내고 새로 로드해야하므로 컨텍스트 스위칭이 일어나면 시간 소요가 일어난다(컨텍스트 스위치 만을 위한 어떠한 작업을 하는것이아닌 즉 성능이 떨어진다.)

 

컨텍스트 스위칭은 일어나면 일어날수록 성능을 저하시키는 요인이고 많은 데이터를 바꾸면 바꿀수록 성능이 떨어진다.

그래서 더 큰 단위인 프로세스를 교환할때 더 많은 시간을 요구하고 프로세스 내부에서 데이터 code,data,heap (스택을 제외한 모든영역) 을 공유하고있는 쓰레드의 컨텍스트 스위칭은 비용이 그나마 적게 든다 어찌되었건 컨텍스트 스위칭이 많은것은 == 성능저하 이다. 

 

또한 쓰레드의 컨텍스트 스위칭이 매우 빠른 이유중 하나는 캐쉬 때문이다 -> 캐쉬는 메인 메모리(RAM)과 CPU(레지스터) 사이에 있는 비교적 빠른 메모리 이다 그래서 cpu 에서 데이터를 한번 읽어드리면 캐시에서 저장하고 있다가 다시 요구할때 좀 더 빠르게 전해주는데

 

프로세스들은 공유하는데이터가 없으므로 프로세스 컨텍스트 스위칭이 일어난다면 당연히 캐쉬에는 겹치는 데이터가 없을것이므로 기존 데이터는 모두 없애야하고 새로 캐시 정보를 쌓아야할것이다. ->  그에 반해 쓰레드는 공유하는 데이터가 있으므로 캐쉬를 이용할수있으므로 빠른 컨텍스트 스위칭이 가능하다.

 

2. 프로세스 

실행파일을 클릭했을 때 메모리(RAM)할당이 이루어지고 메모리공간으로 코드가 올라간것을 의미한다.

CPU의 스케쥴링 대상이 되는 작업(task)라는 용어와 거의 같은 의미로 쓰이기도 한다.

 

한마디로 그냥 프로그램 하나를 지칭하는 단위인데 프로그램이 돌아가려면 여러가지 필수 정보들이 있을 것이다. 그것들이 메모리에 올라가 프로그램이 돌아가는것이되는 순간 프로세스라고 지칭하는것이다.

(프로세스는 그냥 쓰레드를 들고있는 단위라고 생각하면될것 같다 그리고 컨텍스트 스위칭 느리고)

 

참고로 프로세스 끼리는 서로 데이터를 공유할수없고 각각 고유한 메모리 영역을 가진다 

->프로세스 끼리 데이터를 주고받으려면 IPC 라는 것을 거쳐야한다.

 

3. 쓰레드

자 어떻게보면 이글에서 코루틴 다음으로 중점적으로 살펴보려는 것이기도하다.

한줄요약으로 설명하자면 작성해놓은 코드를 무언가가 쭉 읽어내려가면서 실행을 할것이다. -> 그 읽어내려가고 있는 주체이다.

즉 코드를 한줄 한줄 읽고있는놈이다.(현재 cpu에서 읽고 있는 단위 시분할에서 가져가는 조각조각을 생각하면될 것이다.)

결국 멀티쓰레드 즉 코드를 읽는놈을 늘려 비동기 처리를 하게될것이다(어짜피 cpu는 하나겠지만 시분할을 통해서 동시성을 제공).

여태까지 본 모든 thread,ExecutorServices,Rx 등 비동기 처리한 것들은 쓰레드를 늘려놓고 어떻게 행동할건지 정해주는 방법일 뿐이였다 결국 결론은 쓰레드가 근본이고 쓰레드의 개념을 익히면 비동기 처리는 저절로 따라올 것이다.

 

 

 

임시저장 불안해서 일단 저장 추후 수정할것입니다


출처:

https://steady-coding.tistory.com/305

 

JVM 메모리 구조란? (JAVA)

안녕하세요? 코딩 중독입니다. 오늘은 JVM 메모리 구조에 대해 알아보겠습니다. JVM이란? JVM 메모리 구조를 설명하기 전에 JVM이 무엇인지 알아야 합니다. JVM은 Java Virtual Machine의 약자로, 자바 가상

steady-coding.tistory.com

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

 

Coroutine, Thread 와의 차이와 그 특징

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

aaronryu.github.io

https://junshock5.tistory.com/117

 

프로세스, 스레드의 컨텍스트 스위칭 cpu와의 관계

프로세스(process)란? 실행파일을 클릭했을 때, 메모리(RAM) 할당이 이루어지고, 이 메모리 공간으로 코드가 올라간다. 이 순간부터 이 프로그램은 '프로세스'라 불리게 된다. 즉, 사용자가 작성한

junshock5.tistory.com

https://kotlinworld.com/139?category=973476 

 

[Coroutine] 1. Coroutine 은 어떻게 스레드 작업을 최적화 하는가?

Thread 구조와 다중 Thread 작업의 필요성 하나의 프로세스(Process) 에는 여러 스레드(Thread) 가 있고, 각 스레드는 독립적으로 작업을 수행할 수 있다. 예를 들어 JVM 프로세스 상에서는 스레드는 그림1

kotlinworld.com

https://devlog-wjdrbs96.tistory.com/145

 

[Java] 프로세스(process)와 쓰레드(Thread)의 개념과 구현

프로세스(process)란 간단히 말해서 '실행 중인 프로그램(program)'이다. 프로그램을 실행하면 OS로부터 실행에 필요한 자원(메모리)을 할당받아 프로세스가 된다. 그리고 프로그램을 수행하는 데 필

devlog-wjdrbs96.tistory.com