멀티프로세싱과 멀티스레딩
멀티프로세싱(Multiprocessing)과 멀티스레딩(Multithreading)은 현대 소프트웨어에서 동시에 여러 작업을 수행하기 위한 대표적인 두 가지 병렬(또는 병행) 처리 기법임.
CPU 코어가 늘어나고 고성능 환경이 요구됨에 따라, 이 두 방식을 적절히 활용하는 것은 프로그래밍과 시스템 설계에서 매우 중요한 주제가 됨.
기본 정의와 개념 : 멀티 프로세싱
1. 정의
물리적으로 여러 개의 프로세스를 동시에 실행하는 것을 말함.
여러 프로세스를 활용해 병렬 처리를 수행하고, 각각의 프로세스는 운영체제로부터 독립된 자원(메모리 공간, 파일 디스크립터 등)을 할당받음.
2. 운영체제 레벨에서의 특징
운영체제마다 약간씩 다르지만, 보통 각 프로세스는 별도의 주소 공간을 가짐.
프로세스 간 통신(IPC, Inter-Process Communication)은 파이프, 소켓, 공유 메모리, 메시지 큐, 시그널 등을 통해 이뤄짐.
새로운 프로세스 생성 시(예: fork() 또는 createProcess() 등) 비교적 큰 오버헤드가 발생함.(PCB 생성, 메모리 할당 등).
3. 장점
각 프로세스가 독립적인 메모리 공간을 사용하므로, 한 프로세스가 오류로 중단되더라도 다른 프로세스에 직접적인 영향을 주지 않음(격리도가 높음).
보안, 안정성 측면에서 우수함.
멀티코어 환경에서 물리적으로 병렬 실행이 가능함(특히 CPU 코어 수가 많을수록 효과적).
4. 단점
프로세스 생성 및 문맥 교환(Context Switching) 오버헤드가 큼.
프로세스 간 데이터 교환이 복잡하고 느리며, 별도의 IPC 기법을 사용해야 함.
기본 정의와 개념 : 멀티스레딩
1. 정의
하나의 프로세스 내부에서 여러 스레드를 병렬(또는 병행)로 실행하는 것을 말함
스레드는 프로세스가 할당받은 공유 자원(코드 영역, 힙, 전역 메모리 등)을 공유하고, 각 스레드는 자체적인 스택과 레지스터를 가짐.
2. 운영체제 레벨에서의 특징
운영체제는 “스레드”를 독립적인 실행 단위(Kernel-Level Thread)로 인식하고 스케줄링할 수 있음.
스레드 사이의 통신은 같은 프로세스 메모리를 사용하므로 오버헤드가 낮고 빠름.
잘못된 동기화로 인해 스레드 간 “레이스 컨디션(Race Condition)”이 발생하기 쉬움.
3. 장점
스레드 생성, 종료, 문맥 교환 오버헤드가 상대적으로 작음.
데이터 공유가 쉽고 빠름(메모리를 공유하므로).
많은 동시 연결(I/O 바운드 상황)을 처리할 때 효율적임(예: 웹 서버).
4. 단점
공유 메모리 사용 시 동기화 이슈가 발생하여, 설계가 복잡해지고 잠재적인 버그(데드락, 경합 조건 등)를 유발할 수 있음.
하나의 스레드에서 문제가 발생(예: 세그멘테이션 폴트)하면 전체 프로세스가 종료될 수 있음(안정성↓).
동시성과 병렬성
1. 동시성(Concurrency)
여러 작업이 “논리적으로” 동시에 실행되는 것처럼 보이거나, CPU 스케줄러에 의해 빠른 전환이 이루어져 사용자가 동시에 실행되는 것처럼 느끼는 상태를 말함.
단일 코어에서도 “시분할”을 통해 동시성 구현이 가능함.
2. 병렬성(Parallelism)
실제로 여러 CPU 코어(또는 CPU + GPU 등)를 사용하여 “물리적으로” 동시에 여러 작업을 수행하는 것을 말함.
멀티코어 환경에서만 가능한 개념임.
멀티프로세싱과 멀티스레딩 모두 멀티코어 환경에서 동시성과 병렬성을 구현할 수 있으나, 멀티프로세싱은 “서로 다른 프로세스”가 병렬로, 멀티스레딩은 “하나의 프로세스 내부의 여러 스레드”가 병렬로 실행된다는 점에서 차이가 있음.
자원 할당 및 관리 : 멀티프로세싱 자원 관리
1. 메모리 구조
각 프로세스는 코드 세그먼트, 데이터 세그먼트, 힙(Heap), 스택(Stack)을 독립적으로 소유함.
따라서 다른 프로세스에 직접 접근이 불가능하며, IPC를 통해서만 정보를 교환함.
2. 프로세스 간 통신(IPC)
공유 메모리(특수 시스템 콜 필요), 메시지 큐, 파이프, 소켓, 시그널 등 다양한 기법으로 통신함.
IPC 채널 생성 및 관리에 따른 추가 오버헤드가 있음.
3. 스케줄링 및 부하 분산
OS는 각 프로세스를 스케줄링 단위(태스크)로 관리함.
멀티코어 환경에서는 프로세스가 여러 코어에 나뉘어 배치될 수 있음.
프로세스가 많아질수록 PCB 관리, 캐시 로컬리티 문제 등이 발생해 성능 저하를 유발할 수 있음.
자원 할당 및 관리 : 멀티스레딩 자원 관리
1. 메모리 공유 구조
같은 프로세스 내 스레드들은 코드, 데이터, 힙 영역을 공유하지만, 각 스레드는 별도의 스택과 레지스터를 가짐.
전역 변수나 힙 영역에 접근할 수 있으므로, 공유 자원에 대한 동기화가 필수적임.
2. 동기화 기법
스레드 간 동기화 오버헤드(뮤텍스, 세마포어, 모니터, 조건 변수 등)를 잘 관리해야 함.
동기화 객체 설계에 따라 스레드 안전성 및 프로그램 성능이 크게 달라짐.
3. 스케줄링
운영체제에서 스레드를 직접 스케줄링(Kernel-Level Thread)하거나, 유저 레벨에서 스케줄링(User-Level Thread)할 수도 있음.
CPU 코어가 많다면 여러 스레드를 동시에 물리적으로 실행할 수 있음(병렬성).
성능 고려사항 : 프로세스 생성/종료 오버헤드
1. 프로세스
새로운 프로세스 생성 시, 운영체제는 PCB(Process Control Block)를 만들고 독립된 메모리 공간을 준비해야 함.
일반적으로 fork()가 스냅샷 복사를 한다거나(※ Copy-On-Write 최적화가 있더라도), Windows 계열의 CreateProcess() 등이 큰 작업을 수반함.
2. 스레드
스레드는 기존 프로세스의 자원 대부분을 공유하므로, 생성 시 필요한 작업이 상대적으로 적음.
따라서 동시에 많은 작업(예: 수백~수천 개)을 신속하게 처리해야 할 때는 멀티스레딩이 일반적으로 더 유리함.
성능 고려사항 : 문맥 교환 비용
1. 프로세스 문맥 교환
CPU가 실행 중인 프로세스를 다른 프로세스로 전환할 때, 가상 메모리 주소 공간 교체, PCB 교체, 캐시 무효화 등의 무거운 작업이 수반될 수 있음.
2. 스레드 문맥 교환
하나의 프로세스 안에서 스레드가 전환될 때는, 해당 프로세스의 메모리 공간(주소 공간)은 그대로이므로, 레지스터·스택 포인터 정도만 교체하면 됨.
상대적으로 훨씬 가벼움.
성능 고려사항 : 캐시 로컬리티와 NUMA
멀티코어 시스템에서 코어 간 캐시 공유 구조 및 메모리 접근(특히 NUMA, Non-Uniform Memory Access) 구조도 성능에 영향을 줌.
멀티프로세싱은 서로 다른 프로세스가 서로 다른 CPU 코어에서 독립적으로 동작할 때 캐시 로컬리티가 좋아질 수 있지만, IPC 시에는 오버헤드가 높아질 수 있음.
멀티스레딩은 공유 메모리에 대한 접근이 많으므로, 코어 간 캐시 동기화 비용이 발생할 수 있지만, 데이터가 잘 공유된다면 메모리 복사 등을 줄일 수 있어 유리할 수도 있음.
활용 사례 : 멀티프로세싱의 예시
1. 독립적 서비스 구동
웹 서버, 데이터베이스 서버, 캐시 서버 등 서로 다른 프로세스로 분할 배치(마이크로서비스 아키텍처 등).
프로세스 간 통신은 네트워크 소켓, 메시지 큐 등을 이용.
2. 보안·안정성 요구가 높은 환경
프로세스 간 격리를 통해 하나의 프로세스가 다운되더라도 전체 시스템 영향을 최소화(샌드박싱, 컨테이너 등).
3. 언어 런타임 차원
파이썬의 GIL(Global Interpreter Lock) 제약을 우회하기 위해 multiprocessing 모듈을 사용해 CPU 연산을 병렬화.
여러 CPU 코어를 최대한 활용할 때 자주 쓰임.
활용 사례 : 멀티스레딩의 예시
1. 웹/애플리케이션 서버
하나의 프로세스에서 수십, 수백 개의 스레드를 활용해 다수의 클라이언트 요청을 동시에 처리(I/O 바운드).
스레드 풀(Thread Pool)을 만들어 재활용함으로써 스레드 생성/삭제 오버헤드를 절감.
2. 실시간 대화형 애플리케이션
GUI 프로그램(예: 게임, 영상 처리)에서 메인 스레드는 UI를 담당, 다른 스레드는 백그라운드 작업 또는 계산.
3. 멀티코어 병렬 연산
대규모 행렬 연산, 영상 처리, 데이터 분석 등 CPU 연산량이 많은 작업을 여러 스레드로 나누어 병렬 처리.
설계 시 고려사항
1. 격리(안정성) vs. 공유(속도)
멀티프로세싱은 격리가 뛰어나고 안정성이 높은 반면, 프로세스 간 통신 오버헤드가 크고 생성/종료 비용이 높음.
멀티스레딩은 메모리 공유와 빠른 통신이 가능하지만, 동기화 이슈로 인해 설계가 복잡해지며, 문제 발생 시 프로세스 전체가 영향을 받을 수 있음.
2. 작업 특성 파악
CPU 바운드(계산량이 많은) vs. I/O 바운드(네트워크, 디스크 I/O가 많은) 작업에 따라, 혹은 보안 요구 사항, 시스템 규모에 따라 멀티프로세싱 또는 멀티스레딩을 선택하거나 혼합 사용할 수 있음.
3. 운영체제·언어 런타임 환경
일부 언어(Python 등)는 GIL 제약으로 인해 멀티스레딩이 제대로 CPU 병렬 처리로 이어지지 않는 경우가 많음.
이때는 멀티프로세싱, 또는 C/C++로 확장 모듈을 작성하거나, GIL의 영향을 받지 않는 구현(JVM, Go 등)을 사용하는 방안을 고려함.
4. 확장성과 유지보수
서버 애플리케이션은 대개 멀티프로세스 + 멀티스레딩 혼합 구조를 사용하기도 함.
예를 들어, 마스터 프로세스가 관리하고, 각 워커 프로세스나 쓰레드 풀로 나누어 부하를 처리하는 모델(Nginx, Apache의 MPM/Worker 등).
큰 규모의 서비스에서는 멀티프로세스 아키텍처(마이크로서비스)로 서비스 단위를 분리하고, 각 프로세스 내부에서 멀티스레드를 활용하는 것이 일반적임.
정리
1. 멀티프로세싱(Multiprocessing)
각 작업 단위를 독립된 프로세스로 나누어 병렬 처리.
안정성 및 보안성이 높지만, 프로세스 생성/종료/IPC 오버헤드가 큰 편.
2. 멀티스레딩(Multithreading)
하나의 프로세스 내에서 여러 스레드가 메모리를 공유하며 동시에 실행.
빠른 생성, 저비용 통신이 가능하지만, 동기화 및 안전성 문제가 복잡해질 수 있음.
두 방식 중 어떤 것을 선택할지는 프로그램의 특성(연산량, 통신 패턴, 보안 요구 사항, 언어 런타임 제약 등)에 달려 있음.
현대 시스템에서는 종종 두 방식을 혼합해 사용함으로써 병렬 처리 성능과 안정성을 모두 확보하는 설계를 추구함.
'Operating System > Computer' 카테고리의 다른 글
[Computer] 로드밸런서 (0) | 2025.01.29 |
---|---|
[Computer] 프로세스의 문맥 교환 (0) | 2025.01.28 |
[Computer] 프로세스와 스레드의 차이 (0) | 2025.01.27 |
[Computer] CPU 스케줄링 알고리즘 (0) | 2025.01.26 |
[Computer] 자바 표준 스펙 (1) | 2025.01.26 |