학교에서 교양과목으로 C++ 수업을 들었을 때, 교수님이 하신 말씀 중에 기억에 남은 말은 "멀티 쓰레드가 싱글 쓰레드의 경우보다 속도가 무려 10 배가 향상된다." 정도이다. 그리고 C++는 멀티 쓰레드이고, 속도가 빠르기 때문에 하드웨어 내부에서 자주 사용하는 언어이다. 그렇다면, 왜 모든 언어들은 멀티스레드가 아닌 것인가?? 빠른 속도가 부담스러운가??
ex) 자바스크립트는 싱글 스레드(Single thread) 언어라고 알려져 있다.
이 궁금함을 해결해보고자. 이번 글을 작성하기 시작했다.
그런데, 싱글 스레드와 멀티 스레드를 이해하려면, 프로세스에 대한 이해가 필수적이다. 따라서, 이번 시간에는 프로세스와 스레드가 무엇인지에 대해서 정리해보자.
개인적으로, 운영체제의 작동원리에 관해서 무지한 필자는 이 두 개념을 이해하는데 오랜 시간을 투자해야 했다 😂
ex) 크롬 브라우저, VS code, Zoom 등 아직 실행 되지 않은 프로그램들 ( = 코드 덩어리들 )
우리가 Youtube Music을 들으면서, VS code로 코드 작성을 해도 컴퓨터에 렉이 걸리지 않는 이유는 운영체제가 여러 개의 프로세스를 동시에 돌리고 있기 때문이다. => 이것을 멀티테스킹이라고 부른다.
[그림] Window OS 상에서 현재 몇 개의 프로세스가 동작하는지를 보여준다
=> 자신의 컴퓨터에서 확인해보고 싶다면, Window 기준 Ctrl + Alt + Delete 를 누르고, 프로세스 창으로 들어가보자!!!
그리고, 프로세스를 여러 개 돌리는 작업은
하지만, 이렇게만 넘어가기 아쉬우니, 간략하게 각각의 개념에 대해서 살펴보자!!
프로세스 하나가 A라는 작업 조금하고, B라는 작업 조금하고... 이렇게 여러 작업을 돌아가면서, 일부분씩 진행하는 것을 말한다.
이렇게 진행 중인 작업을 A -> B -> C 로 바꾸는 것을 "Context Switching" 이라고 부른다.
Context Switching에는 정말 다양한 방식과 알고리즘이 적용되는데, 이 과정이 너무 빠르게 돌아가니까, 사용자들의 눈에는 마치 모든 작업들이 동시에 진행되는 것처럼 느껴진다.
=> 듀얼코어, 쿼드코어, 옥타코어 등등 이런 명칭이 붙는 멀티코어 프로세서가 달린 컴퓨터에서 할 수 있는 방식이다.
=> CPU의 속도가 발열 문제 등으로 인해서 예전만큼 빠르게 발전하기 못하게 됐다. 다시 말해서, 코어 1개당 속도를 의미하는 GHz를 심한 발열 문제 등으로 높히는데 한계가 생겼다.
이에 대한, 대안책으로 코어의 속도를 높히는 게 어렵다면, 그냥 CORE를 여러개 탑재해서 CPU의 작업 속도를 높히자는 방식이 등장했다.
말하자면, 김종국을 헐크로 만드는 게 너무 어려우니, 여러 명의 김종국을 만들어서 같이 일하게 만드는 것이다! 바로 이것이, 코어를 여러개 달아서 작업을 분담할 수있게 만든 방식 => 즉, 병렬성의 본질이다.
정리하자면, OS 개발자가 될 거 아니라면, OS가 여러 개의 Process를 동시에 돌리고 있는 멀티테스킹을 하고 있어서, 사용자가 컴퓨터에서 여러 작업을 한꺼번에 하고 있어도 렉이 안 걸린다!! => 이 정도로만 알고 넘어가도 좋다.
그런데, 컴퓨터가 여러 개의 프로세스를 동시에 운영할 수 있는 것만으로 충분할까???
다시 말해서, 하나의 프로세스 안에서도 여러가지 작업들이 동시에 진행될 필요가 있다!!
우리는 하나의 프로세서 내에서 동시에 진행되는 작업들 즉, 이 갈래들을 스레드 (Thread)라고 부른다.
그러나, 프로세스와는 다르게 하나의 스레드가 발생한다고 해서, 그것만을 위한 작업 공간을 제공하지는 않는다!!
스레드는 어디까지나 프로세스라는 하나의 프로젝트를 위한 하위 작업 일뿐이다. 개인 작업 공간을 가지고 있는 것보다 같은 프로세스를 위한 스레드들이 같은 작업 공간에서 같은 자원을 공유하는 것이 더 효율적이다.
예시를 들자면, 개발자들끼리 "트위틀러"라는 프로젝트를 진행한다고 가정해보자!!
트위틀러는 " 프로세스 "가 되는 것이다. 그래서, 고유한 작업 공간인 깃헙 저장소를 제공한다.
그리고, 프로젝트를 위한 하위 작업들인 Commit들을 "스레드"라고 볼 수있다.
우리는 각각의 commit을 위해서 저장소를 제공하지는 않는다.
그저, 하나의 트위틀러 저장소에서 자원을 공유하는 것이 작업할 뿐이다!!
=> 이 방법이 확실히 속도와 효율 면에서는 강점을 보인다.
하지만, 모든 것은 장단점이 있는 법!!
단점은 프로세스 안에서 공유되는 특정 변수를 스레드 2개가 동시에 손을 대면, 에러가 발생한다. 마치 같은 파일의 코드를 개발자 2명이 동시에 변경해서 Commit하면, Conflict가 발생해서 resolve가 필요한 것과 같은 상황이다.
=> 이렇게 시간 문제로 발생하는 에러들을 예상하고 방지해야 되기 때문에, 스레드를 사용하는 프로그래밍은 코드를 짜기도 디버깅하기도 매우 까다롭다.
다행히도, 이런 작업들을 더 쉽고 안전하게 하기 위한 도구들이나 프로그래밍 방식들이 나왔다.
2021년에 개발하는 우리들은 너무나 당연하게 사용하지만, 한 때는 혁신이었던 친구들을 몇 명을 소개하겠다.
대표적으로, Closure(클로져), Functional Programming (함수형 프로그래밍), Lambda, Actor 등이 있다.
- 여기까지 프로세스(Process)와 스레드(Thread) 끝!!
싱글 스레드와 멀티 스레드의 차이에 대해서만 알아보려고 했는데, 스레드를 이해하려면 프로세스도 같이 이해해야 되서 학습하는데 시간이 꽤 걸렸다. 덕분에 window 기준에서 exe 파일이 왜 정적인 파일이라고 불리는지 그리고 운영체제가 기본적으로 어떻게 작동하는지에 대해서도 알아볼 수 있는 소중한 경험이었던 것같다.
마지막으로, 관련 자료들이 어렵게 설명 되있어서, 처음 이 개념들을 접하는 주니어 개발자들이 이해하기 힘들 것같다. 이때, 필자의 글이 조금이나마 그들의 이해를 도울 수있기를 바란다.
다음 편에서는 본격적으로 싱글스레드와 멀티스레드에 대해서 자세하게 알아보자 ✌
인터뷰에서 자주 나오는 질문이라 알아두고 싶었는데 정리를 잘 해주셨네요. 잘 읽고 갑니당~