부제 : 이것들은 왜 나오게 되었는가
0.글을 시작하며
멀티프로세싱과 멀티 쓰레딩을 처음 알았을 때는 굉장히 가슴이 설레었습니다.
하나로 처리하던 것을 두개로 처리를 하면 단순히 생각하면 2배로 빨라지니까요
개발자로써 어서 성장해서 이것들을 제어해서 한순가에 프로그램을 빨리 돌릴 생각에 설레던 날이 있었습니다.
하지만 그것이 녹록지 않음을 깨달은 것을 얼마 걸리지 않았습니다.
생각 이상으로 이것들을 제어하는 것은 어려웠으며 오히려 생각만큼 효율적이지도 않을 때도 있었습니다.
이번 글에서는 멀티프로세싱 멀티스레딩을 이야기해보며 왜 나왔고 장단점은 어떠하며
어떤 상황에 써야 효율적으로 사용할 수 있는지를 학습하며 글로 정리해 보려고 합니다.
목차
- CPU와 운영체제의 발전
- 멀티프로세스와 멀티스레드는 왜 나왔는가
- 멀티프로세스와 멀티스레드의 구조적 차이
- 어떤것이 더 좋은가?
- 실제 코드로 실험 해보기
- 멀티프로세스의 장단점
- 멀티스레드의 장단점
- 그렇다면 뭐가 좋은 걸까?
- 마무리
1.CPU와 운영체제의 발전
1-1 한번에 하나씩
초기에 컴퓨터는 한 번에 하나의 프로그램을 실행하며 순차 실행하였습니다.
따라서 어떻게 하면 하나의 프로그램을 빠르게 처리할지를 생각했을 때
CPU의 클럭을 높여서 성능을 높이는 게 주요 발전 방향이었습니다.
1-2 발전에 따라서 프로그램은 여러가지의 일을 하게 되었습니다.
- 음악 프로그램을 재생하며 사용자 입력받기
- 브라우저가 화면을 보여주며 네트워크 응답 기다리기
- 서버는 다수의 사용자의 요청을 처리해야만 함
이런 식으로 여러 요구를 동시에 처리를 하다 보니 문제가 발생합니다.
이는 곧 시분할 처리 방식이 나오게 된 계기가 됩니다.
시분할 처리 방식으로 CPU의 시간을 잘게 나누어서 여러 작업이 동시에 실행 되도록 하였고
실제로 CPU는 빠르게 A, B, C 작업을 번갈아가며 처리하지만
사용자는 동시에 처리되는 것처럼 느낍니다
1-3 단일 코어의 속도 향상의 한계
단일 CPU 성능을 올리는 것에는 한계가 존재합니다.
- 발열
- 전력 소모
- 메모리 병목
- 설계 복잡도 증가
등의 이유로 CPU의 발전 방향은 한 코어를 빠르게 만들 자에서 여러 코어를 두고 병렬로 처리하는 방향으로 발전하게 됩니다.
이 지점부터 멀티 프로세스와 멀티스레드가 점점 의미가 있어집니다.
2. 멀티프로세스와 멀티스레드는 왜 나왔는가
2-1 멀티 프로세스
프로세스는 실행 중인 프로그램의 인스턴스
운영체제는 각 프로세스에 독립된 메모리 공간 제공
프로세스 A, 프로세스 B는 독립된 메모리를 가지며 서로 직접 간섭 불가능
장점
- 서로 간 메모리 간섭 어렵다
- 하나가 문제 생겨도 다른 하나에 영향이 적다
- 보안과 격리에 유리
단점
- 프로세스 생성 비용이 큼
- 메모리를 더 사용
- 서로 데이터를 주고받으려면 IPC 필요
정리 : 안전하지만 무겁다
2-2 멀티스레드
하나의 프로그램에서 여러 흐름을 동시에 처리하고 싶은데, 매번 프로세스를 만드는 건 부담일 때
스레드 : 같은 프로세스 내에서 동작하는 실행 흐름
- 프로세스 내부의 스레드들은 코드, 데이터, 힙 영역 공유
- 하지만 각 스레드는 자기만의 스택과 레지스터를 가짐
장점
- 생성 비용 적음
- 같은 데이터 공유 쉬움
- 빠른 협업 가능
단점
- race condition
- deadlock
- 동기화 비용
- 디버깅 난이도 증가
정리 : 가지만 빠르다
3. 멀티프로세스와 멀티스레드의 구조적 차이
간단히 표로 정리하면 다음과 같습니다.
멀티프로세스 vs 멀티스레드 비교
| 항목 | 멀티프로세스 | 멀티스레드 |
|---|---|---|
| 메모리 공간 | 각자 독립 | 같은 프로세스 안에서 공유 |
| 생성 비용 | 큼 | 상대적으로 작음 |
| 문맥 전환 비용 | 큼 | 상대적으로 작음 |
| 데이터 공유 | IPC 필요 | 메모리 공유 가능 |
| 안정성 | 높음 | 낮음 |
| 장애 영향 범위 | 비교적 분리됨 | 한 스레드 문제로 전체 프로세스 영향 가능 |
| 디버깅 | 상대적으로 단순 | 어려움 |
| 대표 사용 예 | 브라우저 탭 분리, 워커 프로세스, 독립 서비스 | 웹 요청 처리, 백그라운드 작업, UI + 작업 분리 |
4. 어떤것이 더 좋은가?
둘 다 모두 좋다 나쁘다 할 수 없습니다.
작업 종류에 따라 달라집니다
CPU Bound 작업 CPU 계산이 대부분인 작업
- 대량 수학 연산
- 이미지 처리
- 암호화/복호화
- 해시 계산
- 대규모 데이터 변환
CPU를 실제로 얼마나 병렬로 활용한 지가 중요
I/O Bound 작업
CPU 계산보단 기다리는 게 많은 작업
- 파일 읽기/쓰기
- 네트워크 요청
- DB 응답 대기
- 사용자 입력 대기
이경우에는 기다리는 동안 다른 작업을 얼마나 처리 하느냐가 중요합니다.
5. 실제 코드로 실험 해보기
앞에서 이야기드린 것처럼 멀티스레딩 그리고 멀티프로세싱의 가장 큰 차이는 메모리 공간의 공유 여부입니다.
이해를 돕기 위해 자바 코드로 두 가지 방식의 차이를 구현해 보았습니다.
5-1. 멀티스레딩 예시
스레드들은 같은 메모리를 공유할 수 있다는 것을 보여주는 예시입니다. 하나의 공유 객체를 두 개의 스레드가 동시에 접근하여
값을 변경합니다.
class SharedVault {
// 두 스레드가 공유할 공통 변수 (금고)
private int money = 0;
// 의도적으로 synchronized(동기화 자물쇠)를 걸지 않음
public void addMoney() {
money++;
}
public int getMoney() {
return money;
}
}
public class MultiThreadExperiment {
public static void main(String\[\] args) throws InterruptedException {
SharedVault vault = new SharedVault();
// 스레드 A: 금고에 1원씩 10,000번 넣기
Thread threadA = new Thread(() -> {
for (int i = 0; i < 10000; i++) vault.addMoney();
});
// 스레드 B: 금고에 1원씩 10,000번 넣기 (스레드 A와 동일한 금고 공유)
Thread threadB = new Thread(() -> {
for (int i = 0; i < 10000; i++) vault.addMoney();
});
threadA.start();
threadB.start();
threadA.join();
threadB.join();
// 예상 결과는 20,000원이지만, 실제로는 13,421원 등 매번 부족한 금액이 출력됨
System.out.println("최종 금고 잔액: " + vault.getMoney() + "원");
}
}
위 예시 코드의 결과입니다.
멀티 스레드는 하나의 프로세스 내에서 메모리를 공유하기 때문에 이는 데이터를 주고받기 매우 쉽다는 장점이 존재하지만
동시에 여러 스레드가 하나의 데이터에 접근할 때 데이터가 오염되는 경쟁 상태를 유발할 수 있습니다.
왜 20000이 나오지 않을까?
스레드가 +1을 하려고 할 때 최신의 값을 가지고 더한 것이 아니라 아직 갱신되지 않은 옛날의 값을 이용했기 때문
결론 : 스레드는 데이터를 공유하기 때문에 통신 비용이 거의 들지 않아 빠릅니다.
하지만 synchronized 같은 동기화 장치를 마련하지 않으면 치명적인 버그를 낳습니다.
5-2. 멀티프로세싱 예시
프로세스별로 나뉘기 때문에 안전하다는 장점이 존재하지만
프로세스 간 통신(IPC)이라는 번거로운 단점 또한 존재
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class MultiProcessExperiment {
public static void main(String\[\] args) {
System.out.println("부모 프로세스: 자식 프로세스를 생성합니다.");
try {
// 완전히 독립된 새로운 프로세스(OS 명령어)를 실행
// 맥/리눅스: "echo", "Hello Process!" | 윈도우: "cmd.exe", "/c", "echo Hello Process!"
ProcessBuilder pb = new ProcessBuilder("echo", "Hello Process!");
Process childProcess = pb.start(); // 자식 프로세스 탄생
// ★ 핵심: 메모리를 공유하지 않으므로, 자식의 데이터를 변수로 읽을 수 없음!
// 파이프(Stream)를 연결해서 자식 프로세스가 출력한 데이터를 직접 빨아들여야 함 (IPC)
BufferedReader reader = new BufferedReader(
new InputStreamReader(childProcess.getInputStream())
);
String result;
while ((result = reader.readLine()) != null) {
System.out.println("자식 프로세스로부터 받은 메시지: " + result);
}
// 만약 자식 프로세스 내부에서 치명적 에러가 발생해 강제 종료되더라도,
// 부모 프로세스(현재 코드)는 전혀 영향을 받지 않고 끝까지 실행됨 (격리성)
int exitCode = childProcess.waitFor();
System.out.println("부모 프로세스: 자식 프로세스가 안전하게 종료되었습니다. (코드: " + exitCode + ")");
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
위 예시 코드의 결과입니다
.
bufferedReader를 쓴 이유 프로세스 끼리는 메모리를 들여다볼 수 없어서
따라서 스레드처럼 같이 메모리를 쓰는 것이 아니라 데이터 스트림 혹은 소켓으로 데이터를 명시적으로 전송
결론 : 멀티 프로세스는 생성 비용이 크고 데이터를 주고받기 까다 롭다.
다만 자식 프로세스가 오류 나거나 악성코드가 돌아도 부모의 프로세스는 오염되지 않는 안정성을 가짐
6. 멀티프로세스의 장단점
이를 통해 멀티 프로세스 장단점을 정리하겠습니다.
장점
메모리 공간이 독립적이라 안정성이 높습니다
하나의 프로세스가 문제가 생겨도 다른 프로세스에 영향이 비교적 적습니다.
보안과 격리에 유리합니다
서비스를 분리하거나, 워커를 분리하거나, 장애 전파를 막는 데 좋습니다.
CPU Bound 작업에서 강력할 수 있습니다
여러 코어를 분리된 프로세스로 활용하기 쉽습니다. 단점
생성 비용이 큽니다
프로세스를 새로 띄우는 것은 스레드를 만드는 것보다 무겁습니다.
메모리 사용량이 큽니다
같은 프로그램이라도 프로세스를 나누면 중복 비용이 생깁니다.
통신이 번거롭습니다
서로 데이터를 주고받으려면 파이프, 소켓, 공유 메모리 같은 IPC가 필요합니다.
단점
동기화 문제가 생깁니다
공유 자원을 여러 스레드가 동시에 건드리면 충돌이 발생할 수 있습니다.
버그가 재현되기 어렵습니다
멀티 스레드 버그는 실행 순서에 따라 나타났다 안 나타났다 할 수 있습니다.
하나의 문제로 전체 프로세스가 영향을 받을 수 있습니다
같은 메모리를 공유한다는 장점은 동시에 위험이기도 합니다.
7. 멀티스레드의 장단점
장점
생성과 전환 비용이 상대적으로 작습니다
같은 프로세스 안에서 실행 흐름만 나누기 때문입니다.
데이터 공유가 쉽습니다
같은 메모리 공간을 사용하므로 협업이 자연스럽습니다.
I/O Bound 작업에서 효율적입니다
대기 시간 동안 다른 흐름을 처리하기 좋습니다.
단점
동기화 문제가 생깁니다
공유 자원을 여러 스레드가 동시에 건드리면 충돌이 발생할 수 있습니다.
버그가 재현되기 어렵습니다
멀티스레드 버그는 실행 순서에 따라 나타났다 안 나타났다 할 수 있습니다.
하나의 문제로 전체 프로세스가 영향을 받을 수 있습니다
같은 메모리를 공유한다는 장점은 동시에 위험이기도 합니다.
8. 그렇다면 뭐가 좋은 걸까?
선택의 기준은 내가 풀고자 하는 혹은 해결하고자 하는 문제가 무엇이느냐입니다.
멀티 프로세스가 잘 맞는 경우
안정성과 격리가 중요할 때
워커를 독립적으로 실행하고 싶을 때
CPU 연산이 많고 병렬 처리가 필요할 때
하나가 죽어도 전체 시스템이 같이 죽으면 안 될 때
예:
- 대규모 작업 큐 워커
- 독립 실행형 서비스
- 이미지/영상 처리 파이프라인
- 브라우저 탭/렌더러 분리
- 멀티 스레드가 잘 맞는 경우
- 같은 데이터를 자주 공유해야 할 때
- I/O 작업을 많이 동시에 처리할 때
- 빠른 반응성이 중요할 때
- 프로세스 분리 비용이 부담될 때
예:
- 웹 서버 요청 처리
- 네트워크 클라이언트
- UI 프로그램의 백그라운드 작업
- 게임 내 일부 비동기 작업
9. 마무리
멀티 프로세스 그리고 멀티 스레드는 결국 누가 더 뛰어나다 좋다 할 수 없습니다.
둘의 목적은 비슷하나 그 방법 그리고 그것을 실행하기 위한 비용이 다릅니다.
중요한 것은 이 작업이 어떤 게 중심이고 만드는 사람 입장에서 어떤 관점이 더 중요한지라고 생각합니다.
기술에는 뛰어난 기술 못난 기술보다는 문제를 해결하기 위한 도구라고 생각합니다.
문제의 비용과 구조를 보고 어떤 기술을 써야 할지 판단하는 게 더 중요하다고 생각합니다.
추가 개념
1. 시분할
운영 체제가 CPU 시간을 매우 짧게 나누어 여러 작업을 번갈아 처리하는 방식으로
실제로는 순차 처리에 가깝지만 사용자 입장에서는 동시 처리처럼 느껴지게 함
2. IPC
서로 다른 프로세스가 데이터를 주고받기 위한 통신 방식, 파이프, 소켓, 메시지 큐, 공유 메모리 등
'웹' 카테고리의 다른 글
| API 응답(Response)에 관하여 (9) | 2026.04.08 |
|---|---|
| SDK는 어떤 것 일까? (2) | 2026.03.18 |
| c++ 과 java의 메모리 다루는 차이 (2) | 2026.02.24 |
| 무조건 쓰던 MVC 왜 쓸까? (3) | 2026.02.18 |
| 웹 개발 공부 시작 (0) | 2026.01.27 |