본문 바로가기
Operation System/Theory

[OS] 더 이상 어버버하지말자!! 스레드와 프로세스

by KoB King of Backend 2021. 4. 26.

누군가 저에게 프로세스와 스레드의 차이점에 대해 물었던 적이 있었는데, 명확하게 대답을 못한게 너무 아쉬워서 이 참에 확실히 공부하고 넘어가려 이 글을 쓰게 되었습니다.

 

개념들이 파고파고 들면 밑도 끝도 없는 것 같아서 이 글을 이해하는데 있어 굳이 불필요한 개념들에 대해선 언급하지 않겠습니다.

 

 

 

프로세스와 스레드는 무엇일까?

https://upload.wikimedia.org/wikipedia/commons/thumb/9/9a/Process_vs._thread.svg/1200px-Process_vs._thread.svg.png

 

#프로세스(Process)란?

 

프로세스가 무엇인지 파악하기 전에 프로그램이란 무엇인지 파악할 필요가 있습니다. 프로그램이란 단어는 컴퓨터전공자가 아니여도 대부분의 사람들이 많이 들어봤을 것이고 실제로 사용도 하는 단어일 것입니다. 

 

프로그램 은 어떤 작업을 실행할 수 있는 파일을 의미합니다. 바탕화면에 LoL.exe , Visual Studio.exe 같은 파일들이 있는데 이것들이 프로그램입니다. 더블클릭하였을 때 우리는 프로그램을 실행한다고 합니다.

 

프로세스 는 컴퓨터에서 연속적으로 실행되고 있는 컴퓨터 프로그램을 지칭합니다. 좀 더 쉽게 얘기하자면 어떠한 프로그램을 실행시키기 위한 주체(인스턴스)입니다. 프로그램은 하나지만 이를 실행시킬 수 있는 주체(프로세스)는 여러 개가 될 수 있어서 하나의 프로그램을 여러 번 실행시키면 여러 개의 프로세스를 생성시킬 수 있습니다.

 

왼쪽은 visual studio.exe를 한번만 실행시킨 것이고 오른쪽은 visual studio.exe를 추가적으로 2번 더 실행했습니다.

 

위 사진은 하나의 프로그램(visual studio.exe)를 한번만 실행시킨 것과 추가적으로 2번 더 실행한 이미지입니다. 프로세스는 각각의 독립된 메모리 영역을 할당 받게 되는데 위 이미지처럼 한번 실행시켰을 때보다 3번 실행시켰을 때 메모리를 더 차지 하는 모습을 보실 수 있습니다. 당연히 프로세스 수가 많아지만 컴퓨터에 과부하가 걸려 느려집니다.

 

프로세스의 메모리 영역

 

프로세스의 특징

  • 프로세스는 각각의 독립된 메모리 영역(Code, Data, Stack, Heap의 구조) 을 할당 받는다
  • 기본적으로 프로세스 당 최소 1개의 스레드를 가진다
  • 각 프로세스는 별도의 주소 공간에서 실행되며, 다른 프로세스에 접근이 불가능하다
  • 하지만 IPC(프로세스간 통신, Inter Process Communication) 을 이용하여 다른 프로세스간 접근이 가능하다. 대표적으로 채팅 프로그램을 구현할 때 필요한 Socket이 있다

 

한줄 요약 : 프로그램은 코드 덩어리 파일, 그리고 그 프로그램을 실행하게 한 것이 프로세스

 

#스레드(Thread)란?

 

과거에는 하나의 프로세스만을 이용하여 프로그램을 실행시켰다고 합니다. 하지만 시간이 흘러 프로그램이 복잡해지고 프로세스 하나만을 사용하여 프로그램을 실행하기에는 많이 벅차졌습니다. 그리고 현재는 프로그램 하나가 단순히 한 가지 작업만을 하는 경우는 없습니다. 

 

한 프로그램을 처리하기 위한 프로세스를 여러 개 만들면 되지 않을까? 라고 생각할 수도 있지만 위에서도 언급한 바와 같이 기본적으로 프로세스간 접근이 불가능했기 때문에 여러 개의 프로세스를 이용하여 한 프로그램은 처리하기 위한 것은 불가능하였습니다.

 

이에 따라 프로세스와 다르게 더 작은 실행 단위 개념이 필요하게 되었고, 이것이 바로 스레드(Thread) 입니다.

여담으로 그림에서 스레드가 지렁이처럼 표현되는데 스레드가 번역하면 '실'이여서 지렁이처럼 표현됩니다.

 

프로세스내 스레드의 구조

 

스레드의 특징

  • 스레드는 프로세스의 한계를 극복하기 위해 나온 것이므로 한 프로세스 내에 있는 여러 개의 스레드는 공유가 가능하다
  • 스레드는 프로세스 내에서 각각 stack만 할당받고, Heap 영역을 서로 공유한다
  • 같은 프로세스 내의 스레드는 같은 Heap 영역을 공유하는 반면에 다른 프로세스의 메모리에는 접근이 불가능하다

 

 

 

 

프로세스와 스레드의 차이

 

https://ko.wikipedia.org/wiki

 

위에 언급한 개념을 토대로 프로세스와 스레드는 엄연히 개념부터 다르다는 걸 알 수 있었습니다. OS 안에 프로세스가 존재하고 프로세스 내에 스레드가 존재합니다.

 

OS > Process > Thread

 

 

주목할 점은 프로세스는 IPC와 같은 통신기법을 사용하지 않는 이상 프로세스간 접근이 불가능한 반면에, 스레드는 기본 구조가 stack을 제외한 나머지 메모리 영역을 공유하고 있어 IPC와 같은 통신기법이 없어도 자유롭게 접근이 가능합니다.

 

멀티프로세스와 멀티스레드를 이해하는데 있어 Context-Switching의 대략적인 설명이 필요한 것 같아 간단하게 언급하겠습니다.

 

* Context-Switching 란?

 

현재 실행되고 있는 프로세스나 스레드의 상태를 Register에 저장하고 새로운 프로세스나 스레드를 CPU에 적재하는 것을 말합니다.

 

 

OS는 위와 같은 작업을 계속 반복하게 되는데 스레드가 적을땐 상관 없지만 스레드가 많아진다며 비용이 비싸지고, 속도가 급격하게 느려집니다.

 

 

 

 

 

멀티프로세스와 멀티스레드

 

 

멀티프로세스 는 하나의 OS 안에서 여러 프로세스가 실행되는 것이고, 멀티스레드 는 하나의 프로세스 내에서 여러 작업을 여러 스레드를 이용하여 처리하는 것을 말합니다.

 

멀티프로세스의 장단점은 멀티스레드의 장단점과 대조 되는데 멀티프로세스보다는 멀티스레드를 선호합니다. 그런 이유에 대해서는 위에서 언급한 스레드의 '메모리영역 공유' 라는 특징을 생각해보면 쉽게 유추할 수 있습니다. 

 

(교수님이 말하시길 프로그래밍에 있어서 어떤 행위를 했을 때 그것을 함으로써 얻는 이점에 대해 말해보라 할때 모르겠으면 "속도가 개선되고 메모리 절약이 된다" 라고 하면 거의 다 맞다고 하신다.. 근데 진짜 다 그렇다)

 

멀티스레드의 장점

  • 스레드끼리 메모리를 공유하고 있기 때문에 Context-Switching을 할 때 그 만큼 메모리를 아낄수 있다
  • 메모리영역을 공유하고 있기 때문에 응답시간이 빠르다
  • IPC와 같은 복잡한 통신기법이 필요하지 않다

 

멀티스레드의 단점

  • 메모리영역을 공유하기 때문에 하나의 스레드가 문제가 발생하면 프로그램 전체에 영향을 준다
  • 메모리영역을 공유하기 때문에 동기화 문제가 발생할 수 있다
  • 동기화 문제를 반드시 해결해주어야 한다
  • 설계가 어렵고, 디버깅이 까다롭다

 

멀티스레드를 사용하게 되면 여러 개의 스레드들이 어떤 순서로 실행되는지 알 수가 없습니다. 따라서 여러 쓰레드가 함께 전역 변수와 같은 데이터를 같이 사용할 경우 충돌이 발생할 수 있는데 이를 동기화 문제라고 합니다. 이 행위에 대해서는 스케줄링이 알아서 해주지 않기 때문에 개발자가 직접 구현을 해야하는데 이 부분이 쉽지가 않습니다.

 

멀티프로스세의 장단점 멀티스레드와 반대로 생각하시면 됩니다. '메모리 영역을 공유' 한다는 것이 스레드에게 있어 양날의 검같은 존재이지만 이점이 더 많으니 멀티프로세스보다는 멀티스레드를 선호하고 있습니다.

 

 

 

 

 

 맺으며..

 

프로세스와 스레드는 '공유' 개념을 생각하면 쉽게 이해할 수 있습니다. 기본적으로 프로세스는 프로세스간 접근이 불가능하지만 스레드는 같은 프로세스내 존재하면 접근이 가능합니다.

 

메모리 영역을 공유하기 때문에 메모리를 아낄 수 있고, 응답시간이 빠릅니다. 하지만 또 메모리 영역을 공유하기 때문에 동기화문제가 발생하고 하나의 스레드가 프로세스 전체에 영향을 줄 수 있습니다.

 

멀티프로세스보다 멀티스레드를 선호한다고는 하지만 둘의 쓰임새는 확연히 다르므로 이를 적절하게 알맞는 곳에 사용하는 것이 가장 좋은 것 같습니다.

 

다른 프로세스 내 스레드에 접근할 수 있는 방법은 없는 지 추가로 공부해야겠습니다.

 

읽어주셔서 감사합니다.

 

 

 

 Process, Thread Conference

댓글11

  • 지원 2021.04.27 21:21

    많이 헷갈리는 포인트를 딱 잡아주셨네요! 최고! 더는 어버버 헷갈리지 않을 것 같아요 ^,^
    답글

  • Student 2021.04.28 00:32

    감사합니다 ^^
    답글

  • Yuneui 2021.04.28 01:54

    아래에 대해 곰곰이 생각해 보시기를 추천해 드립니다.

    - "프로세스 하나만을 사용하여 프로그램을 실행하기에는 많이 벅차졌다"고 서술하셨습니다. 동일한 리소스를 사용한다고 가정할 때, 프로세스 하나로 충분히 어떤 프로그램을 원활히 수행할 수 없다면 프로세스 두 개를 만드는 것으로 그 프로그램을 언제나 원활히 수행할 수 있을까요? 아니라면 어떤 경우에 프로세스나 스레드를 늘렸을 때 이득을 볼 수 있을까요? (hint: 단일코어 환경이거나 I/O burst등의 상황이 전제되지 않았다면 이 글의 서술은 전부 의미가 없습니다. 멀티프로세싱이나 멀티스레딩을 설명하려면 멀티코어와 time scheduling을 꼭 언급하셨어야 합니다.)
    - Node.js의 이벤트 루프와 Python 인터프리터의 GIL(Global Interpreter Lock)을 포함하여 많은 애플리케이션은 여전히 싱글스레드 기반으로 동작합니다. 그러면 Node.js는 멀티프로세스로 동작할까요? 본문에 언급하신 것처럼 멀티스레드가 양날의 검이지만 이점이 많아 선호되는 방법이라면 2009년에 최초 릴리스된 Node.js는 왜 싱글스레드 디자인을 채택한 것일까요?
    - 멀티스레딩이 여러 작업을 여러 스레드로 처리하는 것이라고 언급하셨습니다. "작업"이 뜻하는 바에 따라 다르긴 하지만 본질적으로 하나의 프로세스에 속하는 스레드는 모두 하나의 작업을 처리하고 있다고 봐야 합니다. 이것이 무슨 의미일까요?

    마지막으로, 멀티프로세싱과 멀티스레딩을 서로 반대의 성질을 갖는 것처럼 묘사하셨지만 사실 그렇지 않습니다. 글에서 언급한 것과 같이 프로세스와 스레드는 사실상 개념이 다르므로, 멀티프로세싱과 멀티스레딩 역시 개념이 다르다고 볼 수 있습니다. 멀티프로세싱과 멀티스레딩이 같이 이루어지지 말라는 법도 없습니다.
    답글

    • Yuneui 2021.04.28 01:59

      * time scheduling -> time slicing입니다.

    • 우선 Node 관련하여 제 생각입니다.

      - Node가 싱글스레드라는 말은 자바스크립트 엔진이 단일 call stack을 사용한다는 관점에서만 맞는 사실이라고 생각합니다. Node에게 IO를 지원해주는 libuv는 여러 개의 스레드(worker thead)를 사용해서 결국 request 받을때만 싱글스레드이지 request를 처리하는 일에 대해서는 libuv의 멀티스레드(worker thead)를 이용합니다. Node를 만든 이유가 간단한 서버사이드 런타임환경을
      구축하기 위해 만들었는데 멀티쓰레드를 이용하여 구현하게 되면 동기화문제, 고가의 비용, 애초에 자바스크립트가 싱글스레드란 점 때문에 싱글스레드를 채택하지 않았나 싶습니다. 또 싱글스레드이긴 하지만 cluster를 이용하여 멀티스레드로 구현이 가능하기도 하고요.

    • Yuneui 2021.04.28 16:27

      기본적으로 옳은 말입니다. Python도 GIL이 걸려있긴 하지만 멀티스레딩을 지원하기도 하고요. 그러면 애초에 왜 처음부터 멀티스레드 디자인을 채택하지 않았을까요? 왜 굳이 싱글스레드 디자인을 채택해 놓고 libuv 등 스레드풀을 가져다 쓰게 했을까요? 자바스크립트가 싱글스레드라는 표현은 가능한 표현인가요?

      근본적으로 "왜" 스레딩이 필요한지에 대한 서술이 부족해 보입니다. 제가 이렇게 댓글을 쓰는 이유는 "왜"에 대한 생각을 더 해 보는 것이 작성자 분께 유익할 것이라 생각이 들어서 그러는 것이니 불쾌하게 받지 않아 주셨으면 좋겠습니다. 제가 드린 질문들은 댓글로 대답을 해 주실 필요가 없습니다.

    • 아닙니다 ㅎㅎㅎ 주니어 개발자로서 배울것이 많은 저에겐 전혀 불쾌하지 않고 오히려 이런 댓글을 달아주셔서 감사합니다!! Yuneui님의 조언 잘 새겨듣겠습니다. 그리고 나머지 질문에 대해서도 곰곰이 더 생각해보겠습니다.

  • 이상수 2021.04.30 09:02

    다음 시리즈 글도 기대가 되네요 ㅎㅎ
    답글