프로세스란 무엇인가?

스노어·2026년 1월 16일

CS

목록 보기
3/6
post-thumbnail

지난 글에서는 JavaScript 실행 시 Call StackHeap이 어떤 역할을 하는지 정리했다.

이번 글에서는 그 실행 구조가 어떤 단위로 운영체제에 의해 관리되는지, 프로세스(Process)를 살펴보겠다.


💡 왜 프로세스를 알아야 할까?

Node.js 서버를 만들다 보면 이런 순간을 만나게 된다.

  • 서버를 실행했는데, 이게 정확히 "뭐 하나"가 실행된 건지 헷갈릴 때
  • 메모리는 아직 남아 있는데 프로세스가 죽는 상황
  • 서버가 오래 켜져 있을수록 점점 느려지는 이유
  • "Node.js는 싱글 스레드다" 라는 말을 들었지만 감이 안 올 때

이 질문들의 공통점은 모두 프로세스 단위에서 시작된다는 점이다.

📌 핵심: JavaScript 코드는 혼자서 실행되지 않는다. 항상 운영체제 위에서, 프로세스라는 실행 단위로 관리된다.


🖥️ 프로세스란 무엇인가?

💬 프로세스(Process) 란?
실행 중인 프로그램을 의미한다.
디스크에 저장된 파일이 메모리에 올라와 실제로 동작하고 있는 상태를 프로세스라고 부른다.

프로세스는 간단히 말해 실행 중인 프로그램 하나이다.

디스크에 있던 프로그램 파일이 실행되면,

  • 메모리에 올라가고
  • 운영체제로부터 실행 권한을 받고
  • CPU 스케줄링의 대상이 된다

이 상태가 바로 프로세스다.


🔄 CPU 스케줄링이란?

💬 CPU 스케줄링(CPU Scheduling) 이란?
운영체제가 여러 프로그램에게 CPU 사용 시간을 번갈아 배분하는 것이다.
마치 선생님이 여러 학생의 질문을 순서대로 빠르게 처리하는 것과 비슷하다.

여러 프로그램이 동시에 실행되는 것처럼 보이지만, 사실 CPU는 한 번에 하나씩만 처리한다.

운영체제가 각 프로세스에게 CPU를 아주 짧은 시간 단위로 번갈아 배분한다.

💻 CPU 스케줄링 예시

시간: 0ms~10ms   → 프로세스 A 실행
시간: 10ms~20ms  → 프로세스 B 실행
시간: 20ms~30ms  → 프로세스 C 실행
시간: 30ms~40ms  → 프로세스 A 실행 (다시)
...

⚡ 이렇게 빠르게 번갈아 실행되어서 
   사용자는 "동시에" 실행되는 것처럼 느낀다

📚 프로그램 vs 프로세스

구분프로그램프로세스
상태정적(Static)동적(Dynamic)
위치디스크에 저장메모리에 적재
비유요리 레시피 책실제로 요리하는 과정
예시app.js 파일실행 중인 node app.js

프로그램디스크에 저장된 정적인 파일이고
프로세스메모리에서 실행 중인 상태다


🔗 프로세스는 메모리 구조를 포함한다

여기서 중요한 점은 프로세스가 새로운 개념이 아니라, 지금까지 살펴본 Call StackHeap, 그리고 Code를 하나로 묶어 관리하는 단위라는 것이다.

Code, Call Stack, Heap, 이 모든 것을 운영체제"하나의 실행 덩어리"로 관리할 때 그 단위를 프로세스라고 부른다.


📦 프로세스의 메모리 구조 상세 설명

프로세스가 실행될 때 메모리에는 세 가지 주요 영역이 구성된다.


📜 Code 영역이란?

💬 Code 영역(Text Segment) 이란?
실행할 프로그램의 코드(명령어)가 저장되는 메모리 공간이다.
JavaScript 파일이 메모리에 올라올 때, 실제 실행 가능한 형태로 변환된 명령어들이 이곳에 저장된다.

Code 영역프로그램의 실행 명령어가 저장되는 공간이다.

📚 Code 영역의 특징

특징설명
읽기 전용프로그램 실행 중 변경되지 않음
공유 가능같은 프로그램을 여러 번 실행해도 Code는 하나
고정 크기프로그램 시작 시 크기가 결정됨
📂 디스크의 app.js
const user = { name: "Kim" };
console.log(user);
         ↓ 로드 & 변환
         
🧠 메모리의 Code 영역
[기계어 명령어들]
0x1000: LOAD "Kim"
0x1004: CREATE_OBJECT
0x1008: CALL console.log
...

왜 읽기 전용일까?

코드는 실행 중에 변경될 필요가 없다. 프로그램의 로직 자체를 바꾸는 게 아니라, 데이터만 변경하면 되기 때문이다.


🔄 Stack, Heap, Code의 관계

📦 프로세스 메모리 구조

┌─────────────────────────┐
│  📜 Code (실행 명령어)   │ ← 읽기 전용, 변경 안 됨
│  "무엇을 실행할지": function add() {...}
├─────────────────────────┤
│  📚 Call Stack          │ ← 함수 호출 순서
│  "지금 어디를 실행 중"    │   예: add()multiply()
├─────────────────────────┤
│  📦 Heap                │ ← 동적 데이터
│  "실행 중 생성된 데이터"  │   예: { name: "Kim" }
└─────────────────────────┘

쉽게 말하면:

  • Code = 요리 레시피 책 (요리법)
  • Stack = 요리 순서표 (지금 어디까지?)
  • Heap = 재료 보관함 (실제 재료)

실행 흐름 예시

// 1️⃣ Code 영역에 저장된 코드
function greet(name) {
  const message = `Hello, ${name}`;
  console.log(message);
}

greet("Kim");

// 2️⃣ 실행 시 각 영역의 상태

📜 Code 영역:
- greet 함수의 명령어들
- console.log의 명령어들

📚 Stack 영역:
- greet("Kim") 실행 프레임
  - 매개변수: name = "Kim"
  - 지역변수: message

📦 Heap 영역:
- 문자열 "Hello, Kim" 저장

📌 정리하면
Code 영역은 "실행할 명령어"를 저장하고,
Stack은 "실행 순서"를 관리하고,
Heap은 "실행 중 생성된 데이터"를 보관한다.


🔄 프로그램 실행 흐름 다시 정리

이제까지의 흐름을 한 번 다시 정리해보자.

1️⃣ JavaScript 파일은 디스크에 저장되어 있다
    ↓
2️⃣ 실행 명령을 내리면 (node app.js)3️⃣ 운영체제가 해당 프로그램을 메모리에 올린다
    ↓
4️⃣ 실행에 필요한 정보들을 구성한다
    - Code 영역에 실행 명령어 적재
    - Call Stack 생성
    - Heap 영역 할당
    - 프로세스 ID 부여
    ↓
5️⃣ CPU가 이 실행 단위를 번갈아 처리한다
    ↓
✅ 프로세스가 실행 중인 상태!

이때 운영체제가 관리하는 실행 단위가 바로 프로세스다.


🎯 운영체제가 프로세스를 관리한다는 의미

💬 운영체제의 프로세스 관리 란?
프로세스가 실행되는 동안 필요한 모든 자원을 할당하고, 상태를 추적하고, 문제가 생기면 종료시키는 일련의 과정이다.

운영체제프로세스를 관리한다는 말은 다음과 같은 일을 대신해준다는 뜻이다:

관리 항목설명예시
실행 추적지금 어떤 프로그램이 실행 중인지 기록Chrome, VSCode, Node.js 서버
CPU 할당CPU를 언제, 얼마나 쓸 수 있는지 결정10ms 동안 실행 → 다른 프로세스에게 양보
메모리 제한메모리를 어디까지 쓸 수 있는지 제한프로세스 A는 0x1000~0x5000 영역 사용
오류 처리문제가 생기면 프로세스를 종료메모리 부족 시 강제 종료

즉, 프로세스운영체제의 관리 아래에서만 실행될 수 있다.


📋 프로세스는 무엇을 가지고 있을까?

프로세스는 실행을 위해 자기만의 자원을 가진다.

🎒 프로세스가 가지는 자원들

자원설명비유
독립적인 메모리 공간Code / Stack / Heap 영역개인 책상 공간
프로세스 ID (PID)운영체제가 부여하는 고유 번호학생 번호
CPU 레지스터 상태현재 실행 위치와 계산 값지금 읽고 있는 책의 페이지 번호
열린 파일 정보사용 중인 파일 목록펼쳐둔 노트와 교과서

🆔 프로세스 ID (PID)란?

💬 PID (Process ID) 란?
운영체제가 각 프로세스를 구분하기 위해 부여하는 고유한 숫자다.
마치 학생마다 고유한 학생 번호가 있는 것처럼, 프로세스마다 고유한 번호가 있다.

# 실행 중인 Node.js 프로세스 확인
$ ps aux | grep node

USER   PID   CPU  MEM   COMMAND
kim    1234  2.5  1.2   node server.js
kim    5678  1.0  0.8   node worker.js

위 예시에서 12345678이 바로 PID다.


💾 CPU 레지스터란?

💬 CPU 레지스터(CPU Register) 란?
CPU 내부의 아주 빠른 임시 저장 공간이다.
"지금 어느 줄을 실행하고 있는지", "계산 중인 값은 무엇인지" 같은 정보를 저장한다.

프로세스가 실행 중일 때:

  • 현재 실행 중인 코드의 위치
  • 계산 중인 값
  • 함수 호출 정보

같은 것들이 CPU 레지스터에 저장된다.

왜 중요한가?

프로세스가 잠시 멈추고 다른 프로세스가 실행될 때, 이 정보를 저장해두었다가 나중에 다시 불러와서 이어서 실행할 수 있다.

🔄 CPU 레지스터 상태 저장/복원 과정

프로세스 A 실행 중:
[레지스터] 현재 줄: 42, 계산값: 10010ms 경과 → CPU 스케줄링
         ↓
[레지스터 내용 저장] → 메모리에 백업
프로세스 B 실행 시작
         ↓
10ms 경과 → CPU 스케줄링
         ↓
[레지스터 내용 복원] ← 메모리에서 불러옴
프로세스 A 다시 실행: 42번째 줄부터 이어서 실행

🚧 프로세스끼리는 메모리를 공유하지 않는다

중요한 점은 프로세스끼리는 메모리를 직접 공유하지 않는다는 것이다.

즉,

한 프로세스가 사용하는 Heap
다른 프로세스에서 접근할 수 없다

이 독립성이 프로세스의 가장 큰 특징이다.

장점: 한 프로세스가 문제를 일으켜도 다른 프로세스에 영향을 주지 않는다
단점: 프로세스끼리 데이터를 주고받으려면 특별한 방법(IPC)이 필요하다

💬 IPC (Inter-Process Communication) 란?
프로세스 간 통신을 의미한다. 독립적인 프로세스들이 데이터를 주고받기 위한 특별한 방법이다. 파이프(Pipe), 소켓(Socket), 공유 메모리(Shared Memory) 같은 기술들이 있다.


🖥️ 하나의 서버 = 하나의 프로세스?

Node.js 서버를 실행하면 운영체제

  1. Node.js 런타임을 로드하고
  2. 하나의 프로세스를 생성하고
  3. 그 안에서 JavaScript 코드를 실행한다

즉,

Node.js 서버는 기본적으로 하나의 프로세스로 실행된다


🤔 "하나"의 의미

여기서 말하는 "하나"는 요청 하나가 아니라 실행 주체 하나를 의미한다.

요청은 여러 개가 들어와도
그것을 처리하는 실행 주체는 하나의 프로세스

그래서 Node.js 서버는 "요청 하나당 프로세스 하나"가 아니라, 프로세스 하나가 요청을 계속 처리하는 구조를 가진다.


⏰ 오래 살아 있는 프로세스

프로세스가 살아 있는 동안,

  • 메모리는 계속 유지되고
  • Heap도 계속 누적되며
  • 서버는 요청을 계속 처리한다
🕐 프로세스 생명주기

시작: node server.js 실행
  ↓
[프로세스 생성]
  ↓
┌──────────────────────┐
│  서버 실행 중...      │ ← 계속 살아있음
│  요청 처리 중...      │
│  메모리 사용 중...  (몇 시간, 며칠...)   │
└──────────────────────┘
  ↓
프로세스 종료 (서버 중지)

그래서 Node.js 서버는 "프로그램"이 아니라 "오래 살아 있는 프로세스"라고 보는 게 더 정확하다.


🔀 멀티 프로세스란?

프로세스를 이해했다면 자연스럽게 이런 질문이 나온다.

"그럼 실행 단위를 여러 개로 나누면 더 빠르지 않을까?"

이 질문에 대한 한 가지 답이 멀티 프로세스다.


📚 멀티 프로세스 구조

💬 멀티 프로세스(Multi-Process) 란?
여러 개의 프로세스를 동시에 실행하는 구조다.
각 프로세스는 완전히 독립적으로 동작한다.

멀티 프로세스여러 개의 프로세스를 동시에 실행하는 구조이다.

프로세스

  • 완전히 독립적이고
  • 메모리를 공유하지 않으며
  • 하나가 죽어도 다른 프로세스에 영향이 없다

✅ 멀티 프로세스의 장단점

장점 ✅단점 ❌
안정성: 한 프로세스 오류가 다른 프로세스에 영향 없음자원 소모: 각 프로세스마다 메모리 공간 필요
독립성: 메모리 충돌 걱정 없음속도: 프로세스 생성/제거 비용이 큼
확장성: CPU 코어 수만큼 병렬 처리 가능통신 복잡: 프로세스 간 데이터 공유가 어려움
💰 자원 사용 비교

단일 프로세스:
[프로세스 1] → 메모리 100MB

멀티 프로세스:
[프로세스 1] → 메모리 100MB
[프로세스 2] → 메모리 100MB
[프로세스 3] → 메모리 100MB
[프로세스 4] → 메모리 100MB
────────────────────────────
총 400MB 사용 (4)

안정성은 높지만 그만큼 자원을 많이 사용한다.


🧵 멀티 스레드란?

다른 선택지는 멀티 스레드다.

💬 스레드(Thread) 란?
프로세스 내부의 실행 흐름이다.
하나의 프로세스 안에서 여러 작업을 동시에 처리할 수 있는 단위다.
마치 한 사람(프로세스)이 여러 손(스레드)으로 동시에 일하는 것과 비슷하다.

스레드프로세스 내부의 실행 흐름이다. 하나의 프로세스 안에서 여러 작업 흐름을 동시에 실행할 수 있다.


🔄 멀티 스레드 구조

💬 멀티 스레드(Multi-Thread) 란?
하나의 프로세스 내에서 여러 개의 스레드가 동시에 작업하는 구조다.
메모리는 공유하면서 실행 흐름만 여러 개로 나뉜다.

이 경우,

메모리는 대부분 공유되고
실행 흐름만 여러 갈래로 나뉜다


⚡ 멀티 스레드의 장단점

장점 ✅단점 ❌
속도: 메모리 공유로 빠른 통신복잡성: 동기화 문제 발생
효율: 메모리 사용량 적음안정성: 한 스레드 오류가 전체에 영향
응답성: 여러 작업 동시 처리디버깅: 오류 추적이 어려움

속도는 빠르지만, 복잡한 문제가 생긴다.


⚠️ 멀티 스레드의 주요 문제들

1️⃣ 동기화 문제

💬 동기화(Synchronization) 문제 란?
여러 스레드가 같은 데이터를 동시에 수정하려 할 때 발생하는 문제다.
마치 두 사람이 동시에 같은 문서를 편집하려고 하는 상황과 비슷하다.

❌ 동기화 문제 예시

공유 변수: count = 0

스레드 1                스레드 2
count 읽기 (0)          count 읽기 (0)
count + 1 계산 (1)      count + 1 계산 (1)
count에 1 저장          count에 1 저장

예상 결과: count = 2
실제 결과: count = 1 💥

2️⃣ 경쟁 조건 (Race Condition)

💬 경쟁 조건(Race Condition) 이란?
두 개 이상의 스레드가 공유 자원에 접근할 때, 실행 순서에 따라 결과가 달라지는 상황이다.
마치 두 사람이 마지막 남은 물건을 동시에 집으려는 상황과 비슷하다.

⚠️ 경쟁 조건 예시

잔액: 10000원

스레드 A (출금 5000)      스레드 B (출금 7000)
잔액 읽기 (10000)         잔액 읽기 (10000)
10000 - 5000 계산           10000 - 7000 계산
잔액 = 5000원 저장          잔액 = 3000원 저장

💥 마지막에 저장된 값에 따라 결과가 달라짐!

3️⃣ 데드락 (Deadlock)

💬 데드락(Deadlock) 이란?
두 개 이상의 스레드가 서로가 가진 자원을 기다리며 영원히 멈춰버리는 상황이다.
마치 좁은 길에서 두 차가 서로 비켜주기를 기다리다 둘 다 못 가는 것과 비슷하다.

💀 데드락 예시

자원 A (파일)        자원 B (DB)

스레드 1:           스레드 2:
A 잠금 성공 ✅      B 잠금 성공 ✅
B 잠금 대기...A 잠금 대기... ⏳

서로가 상대방이 가진 자원을 기다리며
영원히 멈춤 💀

🤔 그럼 Node.js는 왜 이 구조를 택했을까?

여기서 중요한 질문이 나온다.

Node.js멀티 스레드 모델을 기본으로 쓰지 않았을까?

이 질문에 답하려면 웹 서버가 주로 무엇을 하는지를 봐야 한다.


🌐 웹 서버의 주요 작업

웹 서버의 대부분 작업은

  • 네트워크 요청 대기
  • 파일 읽기
  • DB 응답 대기

즉, CPU를 계속 쓰는 작업이 아니다.

💻 웹 서버의 작업 분석

CPU 집약적 작업 (적음):
- 데이터 암호화
- 이미지 처리
- 복잡한 계산

I/O 대기 작업 (많음):- HTTP 요청 대기
- 파일 읽기/쓰기
- DB 쿼리 응답 대기
- API 호출 대기

📡 I/O 작업이란?

💬 I/O(Input/Output) 란?
입력과 출력을 의미한다.
파일을 읽고 쓰거나, 네트워크로 데이터를 주고받거나, 데이터베이스에 접근하는 것처럼 프로그램 외부와 데이터를 주고받는 작업을 말한다.
이런 작업들은 CPU가 계산하는 시간보다 외부의 응답을 기다리는 시간이 훨씬 길다.

⏱️ I/O 작업의 시간 비율

파일 읽기 작업:
- CPU 처리 시간: 0.1ms
- 디스크 응답 대기: 10ms
────────────────────────
대기 시간이 100배 더 김!DB 쿼리 작업:
- CPU 처리 시간: 0.5ms  
- DB 응답 대기: 50ms
────────────────────────
대기 시간이 100배 더 김!

Node.js는 이 특성에 맞게

실행 흐름은 단순하게 유지하고
운영체제의 I/O 처리 능력을 적극 활용하는

방향을 선택했다.


🎯 Node.js의 설계 철학

그래서 Node.js

  • 프로세스는 하나
  • JavaScript 실행 흐름도 하나 (싱글 스레드)

라는 구조를 기본으로 가져간다.

🎯 Node.js의 선택

❌ "최대한 많은 일을 동시에 처리하자"
    (멀티 스레드 방식)"하나의 실행 흐름을 막히지 않게 유지하자"
    (싱글 스레드 + 비동기 I/O)

즉, Node.js의 선택은:

전통적인 방식Node.js 방식
여러 스레드로 동시 처리하나의 스레드 + 비동기
복잡하지만 CPU 활용 좋음단순하지만 I/O 효율 좋음
계산 집약적 작업에 유리네트워크/파일 작업에 유리

"최대한 많은 일을 동시에 처리하자"가 아니라,
"하나의 실행 흐름을 막히지 않게 유지하자"에 가깝다.


🎓 정리

✅ 핵심 요약

  • 프로세스실행 중인 프로그램의 단위다
  • 프로세스Code, Stack, Heap을 포함한다
  • Node.js 서버는 기본적으로 하나의 프로세스로 실행된다
  • 프로세스독립적인 메모리 공간을 가진다
  • 멀티 프로세스는 안정적이지만 자원을 많이 사용한다
  • 멀티 스레드는 효율적이지만 동기화 문제가 복잡하다
  • Node.js는 I/O 작업에 최적화된 싱글 스레드 방식을 선택했다

📊 컴퓨터 시스템 전체 구조


🤔 스스로에게 던져볼 질문

이 글을 읽고 나서 다음 질문에 답할 수 있다면 프로세스는 제대로 이해한 것이다:

Q1. 프로그램과 프로세스의 차이는?

A. 프로그램은 디스크에 저장된 정적인 파일이고,
프로세스는 메모리에서 실행 중인 동적인 상태다.

Q2. 프로세스의 메모리 구조는 어떻게 구성되어 있을까?

A. Code 영역 (실행 명령어), Stack (함수 호출 관리), Heap (동적 데이터)으로 구성된다.

Q3. Node.js 서버는 몇 개의 프로세스로 실행될까?

A. 기본적으로 하나의 프로세스로 실행된다.
여러 요청이 들어와도 하나의 프로세스가 모두 처리한다.

Q4. 프로세스끼리 메모리를 공유할 수 있을까?

A. 아니다. 각 프로세스는 독립적인 메모리 공간을 가진다.
데이터를 주고받으려면 IPC 같은 특별한 방법이 필요하다.

Q5. Node.js는 왜 멀티 스레드를 기본으로 쓰지 않을까?

A. 웹 서버는 I/O 대기 작업이 많다.
Node.js는 복잡한 멀티 스레드 대신,
단순한 싱글 스레드 + 비동기 방식으로 I/O를 효율적으로 처리한다.


🌟 왜 이 구조를 알아야 할까?

프로세스 구조를 알아야:

  • 서버가 왜 멈추는지 이해할 수 있다
  • 메모리가 왜 계속 늘어나는지 알 수 있다
  • Node.js의 한계와 장점을 파악할 수 있다
  • 성능 최적화 방향을 잡을 수 있다

특히 서버가 왜 멈추는지, 왜 메모리가 계속 늘어나는지를 구조적으로 생각할 수 있게 된다.


👉 다음 글 예고

다음 글에서는 하나의 프로세스 안에서 실행 흐름이 어떻게 나뉘는지, 그리고 프로세스스레드의 차이를 더 자세히 살펴볼 예정이다.

  • 스레드는 정확히 무엇인가?
  • Node.js싱글 스레드는 정확히 무엇을 의미하는가?
  • 그렇다면 Node.js는 어떻게 동시에 여러 작업을 처리할 수 있는가?
  • 이벤트 루프는 이 구조에서 어떤 역할을 하는가?
profile
눈코딩 재밌게 합시다!

0개의 댓글