프로세스: 실행 중인 프로그램의 인스턴스로, 메모리 상에서 실행되는 독립적인 프로그램 단위
스레드: 프로세스 내부에서 실행되는 작은 작업 단위
- 각각의 프로세스는 최소한 하나 이상의 스레드를 가진다.
- 프로세스는 싱글 스레드 프로세스 또는 멀티 스레드 프로세스일 수도 있다.
- 멀티 스레드 프로세스에서는 여러 스레드가 동시에 작업할 수 있어서 병렬성과 효율성을 향상시키는 데 도움을 준다.
프로세스 vs 스레드
- 프로세스는 스택, 힙, 코드, 데이터 영역을 각각의 프로세스마다 독립적으로 할당 받는다.
- 프로세스는 격리와 안정성: 각 프로세스는 독립적으로 실행되며, 서로의 메모리에 영역에 직접 접근할 수 없다는 장점과 함께 높은 격리와 안정성을 제공한다.
이로 인해, 하나의 프로세스에서 문제가 발생하더라도 다른 프로세스에 영향을 주지 않는다.- IPC(Inter-Process Communication)를 통해 프로세스 간 통신을 수행할 수 있지만, 비용과 복잡성이 높을 수 있다.
- 스레드는 스택 메모리만 독립적으로 할당받고 나머지 메모리 영역(힙, 코드, 데이터)를 공유한다.
- 스레드는 공유와 빠른 통신: 서로의 메모리 공간을 공유하기 때문에 스레드 간의 통신과 데이터 공유가 효율적이다.
- 스레드 간의 동기화와 데이터 일관성 유지가 중요하다.
- 하나의 스레드에서 발생한 문제는 다른 스레드에 영향을 줄 수 있다.
- 생성 시간: 프로세스를 생성하는 데는 스레드를 생성하는 것보다 시간이 오래 걸린다.
- 프로세스를 생성할 때는 독립적인 메모리 공간을 할당하고 초기화해야 하기 때문
- 컨텍스트 스위칭 시간: 스레드 간의 컨텍스트 스위칭 시간이 프로세스 간의 컨텍스트 스위칭 시간에 비해 빠르다.
- 스레드가 메모리를 공유하기 때문에 스위칭이 빠르게 수행될 수 있기 때문
스택: 지역 변수, 매개 변수, 함수 호출 및 재귀 호출에 사용
- 컴파일 시에 크기가 결정되지만 런타임에서 크기가 동적으로 변경될 수 있다.
- 재귀 함수가 호출될 때마다 새로운 스택 프레임이 동적으로 할당되며, 함수 내의 변수 집합이 해당 함수의 다른 인스턴스 변수와 격리되어 상호 간섭하지 않는다.
힙: 동적 할당을 위해 사용되는 메모리 영역
- 런타임에 크기가 결정되며 malloc(), free()와 같은 함수를 통해 메모리를 할당하고 해제
- C++ vector 자료구조
데이터 영역: 컴파일 시에 크기가 결정되며, 정적 할당에 관련된 메모리 영역으로 사용
- Data Segment: 전역 변수, static, const 중 초기화가 되어있는 변수들이 할당되는 공간
→ 0으로 초기화는 제외
- BSS Segment: 전역 변수, static, const 중 0으로 초기화 또는 어떠한 값으로도 초기화가 되어 있지 않은 변수들이 할당되는 공간
- 코드 영역 : 프로그램의 코드
장점
- 격리성과 안정성: 프로세스는 독립된 구조이므로 자원을 공유하지 않아 하나의 프로세스에 문제가 생기더라도 영향을 미치지 않는다.
- 신뢰성: 프로세스 중 일부에 문제가 발생하더라도 다른 프로세스를 이용해서 처리할 수 있으므로 높은 신뢰성을 제공한다.
단점
- 메모리 공간: 프로세스는 독립된 메모리 공간을 가지므로 멀티프로세스 시스템은 멀티스레드 시스템에 비해 더 많은 메모리 공간을 차지한다.
- Context Switching 오버헤드: 여러개의 프로세스를 통해 작업이 진행되면 Context Switching이 자주 발생한다.
→ 스레드에 비해 프로세스는 독립된 자원을 가지고 있어 store & reload 등 무거운 작업이 진행되어 Context Switching 비용이 증가함에 따라 오버헤드 발생할 수 있다.
예시: 웹 브라우저는 멀티프로세스 구조를 가진다.
- 브라우저 프로세스: 탭 관리, 주소 표시줄, 북마크 등사 용자 인터페이스(UI)를 관리
- 랜더러 프로세스: 웹 페이지의 렌더링과 HTML, CSS, JavaScript의 실행 처리
- 플러그인 프로세스: 플래시, PDF 뷰어, 음악 플레이어와 같은 플러그인을 실행
- GPU 프로세스: 그래픽 처리를 담당
IPC (Inter Process Communication): 프로세스 간에 데이터를 주고받고 상호작용하기 위한 매커니즘
- 공유메모리: 여러 프로세스 간에 데이터를 공유하기 위해 메모리를 공유하는 메커니즘
- 어떠한 매개체를 통해 데이터를 주고받는 것이 아닌 메모리 자체를 공유하기 때문에, 데이터의 복사 없이 공유된 메모리 영역에서 데이터를 직접 공유할 수 있으므로 오버헤드가 적음
- 여러 프로세스가 동시에 메모리에 접근할 수 있으므로 동기화가 필요
- 파일: 데이터를 디스크에 저장된 파일을 통해 교환하는 방식
- 소켓: TCP 또는 UDP 기반의 통신을 사용하여 프로세스 간 데이터를 교환하는 방법
- 웹 브라우저가 웹 서버와 통신할 때 HTML 파일을 가져오는 데 사용
- 파이프
- 익명파이프: 부모 프로세스와 자식 프로세스 사이에서 FIFO 구조의 통신 채널을 만들어 데이터를 교환하는 방법
→ 파이프는 기본적으로 단방향 통신을 위한 메커니즘이므로 양방향 통신을 위해 두 개의 익명 파이프를 사용- 명명파이프: 익명파이프의 확장 개념으로, 부모와 자식 프로세스 간뿐만 아니라 네트워크를 통해 다른 시스템 간에도 통신이 가능
→ 클라이언트와 서버간에 파이프를 만들어 통신- 메세지 큐: 큐 형태의 버퍼를 만들어 통신
- 메시지 버퍼를 만들고 이를 통해 프로세스 간 데이터를 전송하며, 송수신 프로세스 간에 비동기적 통신을 지원
- 과정
→ 메시지 큐 초기화: 메시지 큐를 사용하기 전에 해당 큐는 초기화를 통해 메시지 큐가 생성되고 설정
→ 메시지 보내기: 프로듀서는 메시지를 작성하고 메시지 큐에 해당 메시지를 복사하여 큐에 저장한고 전달
→ 메시지 받기: 컨슈머는 메시지 큐에서 메시지를 읽고 처리 (메시지는 복사된 것이므로 원본 데이터의 무결성이 보장)
- 메시지 큐: 비동기적인 통신을 지원하며, 프로듀서(데이터를 생성하는 측)와 컨슈머(데이터를 소비하는 측) 간에 시간의 독립성을 제공
- 한 측의 작업이 다른 측의 작업에 영향을 주지 않음
→ 한 측이 데이터를 보내거나 받을 때 다른 측은 계속해서 작업을 수행할 수 있으며, 시간에 따라 독립적으로 메시지를 보내고 받을 수 있다. 이로 인해 대기 시간 없이 작업을 진행할 수 있다.- 파이프: 단방향 또는 양방향 통신을 지원하는데 사용되며, 데이터는 순차적으로 전달된다.
- 데이터를 보내는 측이 데이터를 보내면, 데이터를 받는 측은 해당 데이터를 수신할 때까지 대기
→ 데이터를 보내는 측과 받는 측 간에 동기화된 작업이 필요
하나의 프로세스 안에서 스레드를 생성해서 자원을 공유하며 작업을 나누어 실행하는 것
장점
- 스레드는 같은 프로세스 내에서 실행되므로 프로세스 내의 자원을 주로 힙 영역을 통해 공유한다.
- 메모리 공간을 효율적으로 활용
- 스레드 간 데이터 및 자원 공유가 간단하며, 통신 비용이 적고 빠르다.
- 스레드 간에 작업량이 적고 대부분의 자원을 공유하기 때문에 Context Switching에 대한 오버헤드가 비교적 적게 발생한다.
- 스레드는 프로세스 내부에서 생성 및 관리되기 때문에 프로세스를 생성할 때 발생하는 시스템 콜 횟수가 줄어든다.
단점
- 동기화 문제: 스레드는 같은 프로세스 내에서 자원을 공유하므로 동기화 문제가 발생할 수 있다.
- 스레드는 같은 프로세스 내에서 실행되므로 하나의 스레드에 문제가 발생하면 다른 스레드에 영향을 미칠 수 있다.
멀티프로세싱은 하나의 프로세스에 장애가 발생하더라도 다른 프로세스에 영향을 미치지 않아 안정성과 격리성이 높지만, 멀티스레딩에 비해 메모리 자원을 많이 사용하고 Context Swtiching 비용이 많아 오버헤드가 발생할 가능성이 비교적 높다.
멀티스레딩은 Context Switching 빠르고 메모리를 적게 차지하며 통신 비용이 적다는 장점이 있지만, 자원을 공유하므로 동기화 문제가 발생할 수 있다.
각각의 장점과 단점을 잘 파악하여 시스템을 적절하게 설계해야한다.
- 웹 브라우저와 같이 병렬로 여러 작업을 처리해야 하는 환경에서 멀티프로세싱과 멀티스레딩을 결합한 아키텍처를 사용하는 것은 효과적이다.
- 멀티프로세싱은 각 탭 또는 창을 독립적인 프로세스로 실행하여 안정성과 격리성을 제공할 수 있다.
- 멀티스레딩을 사용하여 작은 리소스로 다수의 요청을 병렬로 효율적으로 처리하여 시스템의 전체적인 응답시간을 높일 수 있으며, 동시성을 향상시킬 수 있다.
→ 동시성: 서로 독립적인 작업들이 동시에 실행되는 것처럼 보여주는 것