1. 프로세스(Process) / 스레드(Thread)
🔎 프로세스(Process)란
- 운영체제에서는 실행 중인 하나의 애플리케이션을 프로세스
- 운영체제(OS)에서 작업을 할당받아 처리하는 단위
- 메모리에 적재되어 CPU 자원을 할당 받아 실행되는 프로그램.
🔎 프로세스 구성
- Code : 코드 자체를 구성하는 메모리 영역 (프로그램 명령)
- Data : 전역 변수, 정적 변수, 배열 등 (초기화 된 데이터)
- stack : 지역변수, 매개변수, 리턴 값 (임시 메모리 영역)
- Heap : 동적 할당 시 사용 (new(), mallock() 등)
🔎 프로세스 특징
- 프로세스는 각각 독립된 메모리영역(code, data, heap, stack)을 할당받으며, 다른 프로세스의 변수나 자료구조에 접근 불가하다
- 다른 프로세스의 자원에 접근하려면 파이프, 파일, 소켓 등을 이용해 통신해야한다.
- 프로세스는 최소 1개의 메인 스레드를 갖고 있다.
실제로 하나의 프로그램이 실행될 때, 동시에 여러가지 프로세스가 실행되는 경우들이 많습니다.
크레이지 아케이드 게임을 예로 들면, 게임을 하는 동안 물풍선을 맞고 물속에 갇히는 프로세스, 남은 게임 시간을 나타내는 프로세스, 다른 캐틱터들이 움직이는 프로세스 등 여러 프로세스 들이 동시에 진행 됩니다.
이렇듯 하나의 사건이 발생했지만 우리 눈에 동시에 진행되는 것처럼 보일 때, CPU는 여러 프로세스를 왔다갔다 하는 콘테스트 스위칭(Context Switching)
이 발생합니다.
반복이 많아지게 되면 CPU의 부담이 늘어나게 되고, 중복된 자원을 비효율적으로 관리하게 됩니다.
그럴 때 사용하는 것이 멀티 스레드
입니다.
🔎 스레드(Thread)란
- 프로세스의 작업단위
- 한 프로세스 내에서 동작되는 여러 실행의 흐름으로 프로세스 하나에 자원을 공유하면서 일련의 과정을 여러 개를 동시에 실행시킬 수 있는 것을 말합니다.
- 스레드는 사전적 의미로 한 가닥의 실이라는 뜻입니다.
- 한 가지 작업을 실행하기 위해 순차적으로 실행한 코드를 실처럼 이어 놓았다고 해서 유래된 이름입니다. 하나의 스레드는 코드가 실행되는 하나의 흐름이기 때문에, 한 프로세스 내에 스레드가 두 개라면 코드가 실행되는 흐름이 두 개 생긴다는 의미
🔎 스레드(Thread) 특징
-
한 스레드가 프로세스 자원을 변경하면, 이웃 스레드도 그 변경결과를 즉시 볼 수 있다.
-
프로세스 내에서 스레드 간 자원을 공유하거나 하지 않는 경우 둘 다 있다.
-
본적으로 하나의 프로세스가 생성되면 하나의 스레드가 같이 생성되며, 이를 메인 스레드
라고 부르며, 스레드를 추가로 생성하지 않는 한 모든 프로그램 코드는 메인 스레드에서 실행됩니다.
-
멀티 스레드의 경우 프로세스 내에서 stack만 따로 할당받고, code, data, heap 영역은 공유한다.
<멀티 스레드 구조>
💬 다른 자원들은 공유하지만 굳이 스택만 분리해서 사용하는 이유는?
LIFO(Last In First Out) / 후입 선출이라는 스택의 특성과도 연관이 있습니다.
왜냐하면? 코드와 데이터 힙 영역을 공유하는 것에는 큰 문제가 없지만,
스택 영역은 스택이 쌓이면 위에서부터 프로세스가 섞인 채로 순서대로 나오게 되므로
더 복잡해지기 때문에 원활한 실행 흐름을 위해 스택은 따로 독립적으로 존재하게 됩니다.
🔎 멀티 프로세스
- 하나의 응용프로그램을 여러 개의 프로세스로 구성(병렬)하여 각 프로세스가 하나의 태스크를 처리하도록 하는 것이다.
📌 멀티 프로세스의 장점
- 독립된 구조로 안전성이 높음
- 여러 자식 프로세스 중 하나가 죽어도 다른 프로세스에는 영향이 미치지 않아, 정상적으로 수행된다.
📌 멀티 프로세스의 단점
-
멀티 스레드보다 많은 메모리 공간과 CPU 시간을 차지한다.
-
Context Switching의 오버헤드 발생
사전적 의미: CPU에서 여러 프로세스를 돌아가며 작업을 처리하는 것. 동작 중인 프로세스를 대기하며 해당 >>프로세스의 상태(context)를 보관하며, 대기중인 다음 순서의 프로세스가 동작한다.
-
캐쉬 메모리 초기화 등의 무거운 작입이 진행된다.
-
프로세스는 각각 독립된 메모리영역을 할당받기 때문에 프로세스 사이에서 공유하는 메모리가 없어서 캐쉬메모리를 하고 다시 캐쉬 정보를 받아와야 한다.
-
프로세스는 독립된 메모리영역 때문에 프로세스간 자원을 공유할 수 없고, 복잡하고 어려운 통신을 거쳐야 한다.
🔎 멀티 스레드
- 하나의 응용프로그램을 여러 개의 스레드로 구성하고, 각 스레드로 하여금 하나의 작업을 처리하도록 함.
📌 멀티 스레드의 장점
- 멀티 프로세스보다 적은 메모리 공간을 차지하고 context switch가 빠르다.
- 스레드 간 통신에 별도의 자원을 이용하지 않고도, 전역변수 공간이나 heap 영역을 통해 데이터를 주고 받을 수 있다.
- 스택을 제외한 모든 영역이 메모리를 공유하므로 통신 부담이 적다.
📌 멀티 스레드의 단점
- 스레드간 자원을 공유하기 때문에, 하나의 스레드만 오류로 종료되어도 전체 스레드가 종료될 수 있다.
- 동기화문제인
critical section
발생
critical section이란
- 일한 자원을 동시에 접근하는 작업을 실행하는 코드 영역이다.
스레드 간에는 전역 변수를 공유하므로 함께 사용할 때 충돌이 발생할 수 있다.
💡 멀티 프로세스 대신 멀티 스레드를 이용하는 이유는?
-
자원의 효율성 증대
-
멀티스레드로 작업할 경우, 프로세스를 생성하여 자원을 할당하는 시스템콜이 줄어든다.
-
프로세스간 context switch 시, CPU 레지스터뿐만 아니라 RAM과 CPU 사이의 캐쉬까지 초기화되어 오버헤드가 크기때문.
-
스레드는 프로세스 내 메모리(stack 제외)를 공유하기 때문에 통신 비용이 적다.
-
스레드 간 context switch 시, stack만 전환하면 되므로, 전환 속도가 빠르다.
💡 싱글 스레딩 VS 멀티 스레딩
- 상황을 고려해 싱글 or 멀티 스레드를 사용할 것인지에 대한 선택이 필요하다
- 참고로 Javascript의 경우 싱글 스레드 이긴 하나, 이벤트 루프를 통한 비동기 처리를 통해 여러 요청을 처리할 수 있다
📌 싱글 스레드
📌 싱글 스레드의 장점
- 공유자원을 접근하는 동기화 문제를 신경쓰지 않아도 된다.
- context switch 작업을 요구하지 않아서, 전환 비용이 들지 않는다.
- 두 개의 작업에 대해 두 개의 스레드를 할당하여 작업할 경우에도 CPU를 선점하는 과정에서 context switch가 발생하는데, 단일 스레드에 비해 비용이 증가할 수 있다.
📌 싱글 스레드의 단점
📌 멀티 스레드
- 하나의 프로세스에서 다수의 스레드 실행.
- 프로세스 내에서 자원을 공유하여 자원 생성과 관리 중복을 최소화.
- 서버가 많은 요청을 효율적으로 수행할 수 있는 환경 제공.
- 각각의 스레드가 고유의 레지스터와 스택으로 표현된다.
📌 멀티 스레드의 장점
- 새로운 프로세스를 생성하는 것보다 기존 프로세스에서 스레드를 생성하는 것이 빠르다.
- 프로세스의 자원과 상태를 공유하여 효율적으로 운영이 가능하다.
- 프로세스의 작업전환보다 스레드의 작업전환이 더 빠르다.
📌 멀티 스레드의 단점
- 하나의 스레드만 실행중일 때는 실행시간이 오히려 지연될 수 있다.
- 멀티 스레딩을 위해 운영체제의 지원이 필요하다.
- 스레드 스케쥴링을 신경써야 한다.