Process-concept

Kamator0·어제

프로세스 개념 (Process Concept)

운영체제가 실행하는 프로그램의 종류

  • 운영체제는 다양한 프로그램을 실행한다.
시스템 유형program설명
일괄 처리 시스템작업(jobs)여러 작업을 한꺼번에 모아서 순차적으로 처리하는 방식
시분할 시스템사용자 프로그램 또는 태스크(user programs or tasks)여러 사용자가 동시에 시스템을 공유하는 방식
  • 프로그램이란?
    • 프로그램은 수동적 개체(passive entity)이다. 디스크에 저장된 명령어 목록을 담고 있는 파일과 같다.
    • 프로그램 자체는 프로세스가 아니다.

프로그램은 디스크에 가만히 저장되어 있는 파일일 뿐이다. 아직 실행되지 않은 상태이다.

  • UNIX 프로세스란 정확히 무엇인가?

    • 프로세스는 실행 중인 프로그램의 인스턴스(instance)이며, 실행 중인 프로그램이다.
      • 비유: 프로그램은 요리 레시피(책)이고, 프로세스는 그 레시피대로 실제로 요리하고 있는 행위이다. 같은 프로그램에서 여러 프로세스가 만들어질 수 있다 (예: 크롬 브라우저 탭 여러 개).
    • 다음에 실행할 명령어를 지정하는 프로그램 카운터와 자원(메모리, 파일, 소켓 등)의 집합을 가진 능동적 개체(active entity)이다.
  • 프로세스는 가상 주소 공간과 제어 정보로 구성된다

    • 가상 주소 공간: 각 프로세스가 자신만의 독립적인 메모리 공간을 가진 것처럼 보이는 메커니즘 제어 정보: 프로세스 상태, 우선순위, 열린 파일 목록 등 OS가 프로세스를 관리하기 위한 정보

핵심 포인트: 프로그램 = 디스크에 저장된 정적 파일(수동적), 프로세스 = 메모리에 올라가 실행 중인 동적 상태(능동적). 같은 프로그램에서 여러 프로세스가 생성될 수 있다.

메모리 내 프로세스 (Process in Memory)

  • 좌측: 메모리(Memory)

    • 메모리 안에 두 개의 프로세스가 올라가 있다: Internet Explorer(분홍색)와 Word(연두색).
    • 디스크(Disk)에 있던 "word" 프로그램이 화살표를 통해 메모리로 로드되는 과정을 보여준다.
  • 우측: 프로세스의 메모리 레이아웃(주소 공간)

    • 주소 0(최하위)부터 max(최상위)까지:
    • max ┌─────────────┐
          │   stack     │  ← 스택: 위에서 아래로 성장 (↓)
          │      ↓      │
          │             │  ← 빈 공간 (스택과 힙 사이)
          │      ↑      │
          │   heap      │  ← 힙: 아래에서 위로 성장 (↑)
          ├─────────────┤
          │   data      │  ← 데이터 섹션
          ├─────────────┤
          │   text      │  ← 텍스트(코드) 섹션
        0 └─────────────┘
  • Process에 포함되는 것

구성상세 설명
program counter다음에 실행할 명령어의 주소를 가리키는 레지스터
stack함수 호출 시 매개변수, 지역 변수, 리턴 주소가 저장되는 영역. 함수 호출이 중첩되면 스택이 아래로 자란다
data section전역 변수와 정적 변수가 저장되는 영역
Control informationPCB에 저장되는 프로세스 관리 정보
  • 추가로 그림에 보이는 영역들:
    • text (코드): 프로그램의 실행 가능한 기계어 코드가 저장
    • heap (힙): 동적 메모리 할당(malloc, new)을 위한 영역. 아래에서 위로 자란다
    • 스택과 힙은 서로 반대 방향으로 자라며, 두 영역이 만나면 메모리 부족 상태가 된다

핵심 포인트: 프로세스의 메모리는 text(코드) → data(전역변수) → heap(동적할당, ↑성장) → stack(함수호출, ↓성장)의 구조를 가진다. 프로그램이 디스크에서 메모리로 로드되면 프로세스가 된다.

FreeBSD 프로세스의 메모리 예제 (Example: FreeBSD's Process in Memory)

소스 코드와 메모리 매핑

  • 좌측의 C 소스 코드가 우측의 메모리 레이아웃에 어떻게 매핑되는지 보여준다.

디스크 → 메모리 로딩 과정 (그림 우측)

디스크에 저장된 실행 파일(executable-file disk image)의 구조:

a.out magic number  ← 실행 파일 식별자
a.out header        ← 각 섹션의 크기 정보
text                ← 코드 섹션
initialized data    ← 초기화된 데이터
symbol table        ← 심볼 테이블 (디버깅용)

이 파일이 메모리에 로드되면:

  • text → 메모리의 text 영역으로
  • initialized data → 메모리의 initialized data 영역으로
  • bss는 디스크에 저장되지 않고 메모리에서 0으로 채워진다

페이지 테이블 (Page Table)

그림 중앙의 Page table 화살표는 가상 주소를 물리 메모리(Physical memory)로 변환하는 과정을 보여준다.

  • 프로세스가 사용하는 주소(가상 주소)는 실제 물리 메모리 주소와 다르다.
  • 페이지 테이블이 가상 주소 → 물리 주소 매핑을 담당한다.
  • 이를 통해 각 프로세스는 자신만의 독립된 주소 공간을 가진 것처럼 보인다.

핵심 포인트: C 코드의 각 요소(전역 변수, 지역 변수, 동적 할당)가 메모리의 어느 영역에 저장되는지 정확히 이해하는 것이 중요하다. bss는 초기화되지 않은 전역 변수 영역으로 디스크에 저장하지 않아 실행 파일 크기를 줄인다.


프로세스 상태 (Process State)

5가지 프로세스 상태

  • 프로세스가 실행됨에 따라 상태가 변화한다.
상태원문한국어상세 설명
newThe process is being created프로세스가 생성 중fork() 등으로 프로세스가 막 만들어지고 있는 단계
runningInstructions are being executed명령어가 실행 중CPU를 할당받아 실제로 코드가 실행되고 있는 상태
waitingThe process is waiting for some event to occur어떤 이벤트가 발생하기를 기다리는 중I/O 완료, 시그널 수신 등을 기다리는 상태. CPU를 사용하지 않는다
readyThe process is waiting to be assigned to a processor프로세서에 할당되기를 기다리는 중실행 준비가 되었지만 CPU가 다른 프로세스를 실행 중이라 대기
terminatedThe process has finished execution실행이 끝남exit() 호출 등으로 프로세스가 종료된 상태

전이원인한국어 설명
new → readyadmitted (승인됨)OS가 프로세스를 승인하여 준비 큐에 넣는다
ready → runningscheduler dispatch (스케줄러 디스패치)CPU 스케줄러가 이 프로세스를 선택하여 CPU를 할당한다
running → readyinterrupt (인터럽트)타임 슬라이스 만료 등 인터럽트로 CPU를 빼앗긴다
running → waitingI/O or event wait (I/O 또는 이벤트 대기)I/O 요청, sleep() 등으로 이벤트를 기다린다
waiting → readyI/O or event completion (I/O 또는 이벤트 완료)기다리던 이벤트가 완료되어 다시 실행 준비 상태가 된다
running → terminatedexit (종료)프로세스가 실행을 마치고 종료한다

주의: waiting → running으로 직접 전이는 없다. 반드시 waiting → ready → running 순서이다. 즉, I/O가 끝나도 바로 실행되지 않고 준비 큐에서 자기 차례를 기다려야 한다.

핵심 포인트: 프로세스는 new → ready → running → terminated의 기본 흐름을 따르며, running 중 I/O가 필요하면 waiting으로, 타임 슬라이스가 만료되면 ready로 돌아간다.


슬라이드 7 — Unix/BSD 프로세스 상태 (Example: Unix/BSD process state)

  • 실제 Unix/BSD에서는 교과서보다 더 세분화된 프로세스 상태가 있다.

상태 다이어그램 상세 설명

상태한국어설명
initial (idle)초기(유휴)fork()로 프로세스가 막 생성된 상태
user running사용자 모드 실행사용자 모드에서 코드가 실행 중
kernel running커널 모드 실행시스템 콜이나 인터럽트로 커널 코드가 실행 중
ready to run실행 준비CPU 할당을 기다리는 상태
asleep수면I/O 등 이벤트를 기다리며 잠든 상태 (= waiting)
zombie좀비exit()했지만 부모가 wait()하지 않아 정보만 남은 상태
stopped정지SIGSTOP 시그널로 일시 정지된 상태
stopped + asleep정지 + 수면정지 상태에서 동시에 수면 중인 상태

주요 전이

  • user running → kernel running: syscall(시스템 콜)이나 interrupt(인터럽트) 발생 시
  • kernel running → user running: syscall이나 interrupt에서 return(반환) 시
  • kernel running → asleep: sleep() 호출이나 I/O 대기 시
  • asleep → ready to run: wakeup() 호출로 깨어남
  • kernel running → zombie: exit() 호출 시
  • zombie → (제거): 부모의 wait() 호출 시
  • ready to run ↔ stopped: stop(SIGSTOP) / continue(SIGCONT) 시그널로 전환

핵심 포인트: 실제 Unix에서는 user running과 kernel running을 구분하며, 좀비(zombie)와 정지(stopped) 상태가 추가된다. 좀비는 프로세스가 종료되었지만 부모가 아직 회수하지 않은 상태이다.


프로세스 제어 블록 (Process Control Block, PCB)

  • PCB는 각 프로세스에 연관된 정보를 담고 있다.

PCB의 구성 요소

항목원문한국어상세 설명
Process stateready, running, waiting, halted, and so on프로세스 상태현재 프로세스가 어떤 상태인지
Program counteraddress of the next instruction to be executed프로그램 카운터다음에 실행할 명령어의 주소
CPU registersstack points, general purpose registersCPU 레지스터스택 포인터, 범용 레지스터 등의 값
CPU scheduling informationprocess priority, scheduling queue, nice valueCPU 스케줄링 정보프로세스 우선순위, 스케줄링 큐 위치, nice 값
Memory-management informationvalues of base and limit, page table, and so on메모리 관리 정보base/limit 레지스터 값, 페이지 테이블 등
Accounting informationThe amount of CPU and real time used, time limits, etc계정 정보사용한 CPU 시간, 실제 경과 시간, 시간 제한 등
I/O status informationThe list of devices allocated to the process, a list of open files (file descriptor table)I/O 상태 정보할당된 장치 목록, 열린 파일 목록(파일 디스크립터 테이블)

PCB 구조

┌──────────────────┐
│  process state   │  ← ready, running, waiting 등
├──────────────────┤
│  process number  │  ← PID (프로세스 식별자)
├──────────────────┤
│  program counter │  ← 다음 실행할 명령어 주소
├──────────────────┤
│                  │
│    registers     │  ← CPU 레지스터 값들
│                  │
├──────────────────┤
│  memory limits   │  ← 메모리 범위 정보
├──────────────────┤
│list of open files│  ← 열린 파일 목록
├──────────────────┤
│      ...         │  ← 기타 정보
└──────────────────┘
  • PCB는 커널 메모리에 존재하며, 프로세스마다 하나씩 있다.
  • 문맥 전환(context switch) 시 현재 프로세스의 PCB를 저장하고, 새 프로세스의 PCB를 로드한다.

핵심 포인트: PCB는 프로세스의 "신분증"이다. OS는 PCB를 통해 프로세스의 모든 상태 정보를 관리하며, 문맥 전환 시 PCB를 저장/복원하여 프로세스가 중단된 지점에서 다시 실행될 수 있게 한다.


Unix/BSD PCB 예제 (Example: Unix/BSD PCB)

프로세스 테이블 (Process Table)

  • proc 구조체의 고정 크기 배열이다.
  • 이 크기가 동시에 실행할 수 있는 프로세스 수의 상한선(hard limit)을 결정한다.

그림 설명: proc 구조체(process entry)의 포인터 관계

각 항목 설명:

항목한국어설명
process group프로세스 그룹시그널을 함께 받는 프로세스 그룹 → 세션(session)과 연결
process credential프로세스 자격 증명프로세스의 권한 정보 → 사용자 자격 증명(user credential)과 연결
VM space가상 메모리 공간프로세스의 가상 주소 공간 → 영역 리스트(region list)와 연결
file descriptors파일 디스크립터열린 파일 정보 → 파일 엔트리(file entries)와 연결
resource limits자원 제한CPU 시간, 메모리 등의 사용 제한
statistics통계CPU 사용량 등 통계 정보
signal actions시그널 동작각 시그널에 대한 핸들러 지정
process control block프로세스 제어 블록레지스터, PC 등 하드웨어 문맥
process kernel stack프로세스 커널 스택시스템 콜 실행 시 사용하는 커널 스택

핵심 포인트: 실제 Unix에서 프로세스는 단순한 PCB가 아니라, 여러 하위 구조체들의 포인터 네트워크로 이루어져 있다. 프로세스 테이블의 크기가 최대 프로세스 수를 결정한다.


프로세스 스케줄링 (Process Scheduling)

다중프로그래밍 (Multiprogramming) 정의

  • 항상 어떤 프로세스가 실행되도록 하여 CPU 활용률을 극대화한다.
  • 시나리오:
    • 여러 프로그램이 일괄적으로 메모리에 올라가고, 첫 번째 프로그램이 실행을 시작한다.
    • 첫 번째 프로그램이 주변장치를 기다리는 명령에 도달하면, 이 프로그램의 문맥이 저장되고 메모리의 두 번째 프로그램이 실행 기회를 얻는다. 모든 프로그램이 끝날 때까지 이 과정이 반복된다.

시분할 (Time-sharing) 정의

  • 많은 사용자가 컴퓨터를 동시에 공유할 수 있게 한다. 각 사용자에게 약간의 CPU 시간만 필요하다. 각 사용자는 전체 컴퓨터 시스템이 자신만을 위해 전용되고 있다는 인상을 받는다.

프로세스 스케줄링 예시

상단 그림 (다중프로그래밍):

  • Process 0이 CPU를 사용하다가 → I/O가 필요하면 → Process 1이 CPU를 받는다 → I/O가 끝나면 → Process 0이 다시 CPU를 받는다

하단 그림 (시분할/타임 슬라이스):

  • 타임 슬라이스(time quantum) 단위로 프로세스들이 번갈아 CPU를 사용한다.
  • 각 프로세스는 정해진 시간만큼만 CPU를 사용하고, 시간이 만료되면 다음 프로세스에게 넘긴다.

핵심 포인트: 다중프로그래밍은 I/O 대기 시 CPU를 다른 프로세스에 넘기는 것이고, 시분할은 정해진 시간 단위(타임 슬라이스)로 CPU를 번갈아 사용하는 것이다.


프로세스 간 CPU 전환 (CPU Switch From Process to Process)

CPU 전환이 발생하는 3가지 이유 (좌측 빨간 텍스트)

  1. I/O (waiting state): I/O 요청으로 대기 상태로 전환
  2. Time slice expired (ready state): 타임 슬라이스 만료로 준비 상태로 전환
  3. sleep/SIGSTOP (waiting state): sleep() 호출이나 SIGSTOP 시그널로 대기 상태로 전환

전환 과정 상세

단계동작한국어 설명
1P₀ executingP₀가 CPU에서 실행 중
2Interrupt/system call 발생인터럽트나 시스템 콜이 발생
3save state into PCB₀P₀의 현재 상태(레지스터, PC 등)를 PCB₀에 저장
4스케줄러가 다음 프로세스 P₁ 선택OS의 스케줄러가 준비 큐에서 P₁을 선택
5reload state from PCB₁P₁의 저장된 상태를 PCB₁에서 로드
6P₁ executingP₁이 CPU에서 실행 시작 (이전에 중단된 지점부터)

핵심 포인트: Context Switch의 핵심은 "현재 프로세스의 PCB 저장 → 새 프로세스의 PCB 로드"이다. 이 과정에서 CPU는 유용한 작업을 하지 못하므로 오버헤드가 된다.

프로세스 스케줄링 큐 (Process Scheduling Queues)

4가지 큐

원문설명
Job queueSet of all processes in the system시스템 내 모든 프로세스의 집합
Ready queueSet of all processes residing in main memory, ready to execute메인 메모리에 있으며 실행 준비된 프로세스의 집합
Device queuesSet of processes waiting for an I/O deviceI/O 장치를 기다리는 프로세스의 집합
Waiting queue per resourceSet of processes waiting for a resource (e.g., message queue, socket, semaphore, etc)특정 자원(메시지 큐, 소켓, 세마포어 등)을 기다리는 프로세스
  • 프로세스들은 다양한 큐들 사이를 이동(migrate)한다.

Ready Queue와 I/O Device Queue

  • 각 큐는 연결 리스트(linked list)로 구현되며, 큐 헤더에 head(첫 번째)와 tail(마지막) 포인터가 있다.
  • 큐의 각 노드는 PCB이며, PCB 안에 레지스터 정보 등이 포함되어 있다.
  • 준비 큐(ready queue)에는 PCB₇, PCB₂가 대기 중
  • mag tape 1에는 PCB₃, PCB₁₄, PCB₆가 I/O를 기다리며 대기 중

프로세스 스케줄링 표현

CPU를 사용한 후 발생할 수 있는 4가지 상황:
1. I/O request: I/O 요청 → I/O 큐에서 대기 → I/O 완료 후 ready queue로 복귀
2. time slice expired: 타임 슬라이스 만료 → 바로 ready queue로 복귀
3. fork a child: 자식 프로세스 생성 → 자식 실행 완료 후 ready queue로 복귀
4. wait for an interrupt: 인터럽트 대기 → 인터럽트 발생 후 ready queue로 복귀

핵심 포인트: 프로세스는 생명주기 동안 준비 큐, 장치 큐, 대기 큐 사이를 끊임없이 이동한다. 모든 경로는 결국 ready queue로 돌아온다.


스케줄러 (Schedulers)

장기 스케줄러 (Long-term scheduler / Job scheduler)

  • 프로세스 풀에서 어떤 프로세스를 메모리로 가져와 준비 큐에 넣을지 선택한다.
  • Unix/Windows 같은 현대 OS에서 이 스케줄러는 없거나 최소화되어 있다.

단기 스케줄러 (Short-term scheduler / CPU scheduler)

  • 다음에 실행할 프로세스를 선택하고 CPU를 할당한다.

두 스케줄러의 차이

  • 장기/단기 스케줄러의 차이 — 실행 빈도
스케줄러실행 빈도역할
장기 스케줄러매우 드물게 (수 분에 한 번)디스크 → 메모리로 프로세스 로드 결정
단기 스케줄러매우 자주 (수 밀리초마다)CPU에 실행할 프로세스 선택

문맥 전환 (Context Switch)

What is Context Switch?

  • 문맥은 프로세스 제어 블록(PCB)에 표현되며, CPU 레지스터의 값과 프로세스 상태를 포함한다.

문맥 전환 시 일어나는 연산

단계한국어
1현재 프로세스의 PCB를 저장
2실행 예정인 새 프로세스의 저장된 PCB를 로드
3캐시와 TLB가 리셋
  • 문맥 전환 시마다 캐시와 TLB에서 매우 많은 미스(miss)가 발생한다.
  • 새 프로세스의 데이터가 캐시/TLB에 없으므로, 전환 직후에는 성능이 일시적으로 저하된다.
  • 문맥 전환 시간은 오버헤드이다. 전환하는 동안 시스템은 유용한 작업을 하지 못한다.

문맥 전환 구조

  • Store: 현재 프로세스(P₀)의 레지스터, PC 등을 PCB₀에 저장
  • Load: 새 프로세스(P₁)의 PCB₁에서 레지스터, PC 등을 프로세서에 로드
  • TLB와 Cache는 리셋됨 (새 프로세스의 메모리 매핑으로 교체)

핵심 포인트: 문맥 전환 = PCB 저장 + PCB 로드 + 캐시/TLB 리셋. 전환 시간 자체는 순수한 오버헤드이므로, 너무 자주 전환하면 성능이 떨어진다.


프로세스 생성 (Process Creation)

프로세스 트리

  • 부모 프로세스가 자식 프로세스를 생성하고, 자식이 다시 다른 프로세스를 생성하여 프로세스 트리를 형성한다.
  • 프로세스는 고유한 프로세스 식별자(PID)로 식별된다.

자원 공유 옵션

원문설명
Parent and children share all resources부모와 자식이 모든 자원을 공유
Children share subset of parent's resources자식이 부모 자원의 일부를 공유
Parent and child share no resources부모와 자식이 자원을 공유하지 않음

실행 옵션

원문설명
Parent and children execute concurrently부모와 자식이 동시에 실행
Parent waits until children terminate부모가 자식이 종료할 때까지 대기

Solaris 프로세스 트리 그림

각 프로세스 설명:

  • sched (pid=0): 스케줄러. 시스템의 최초 프로세스
  • init (pid=1): 모든 사용자 프로세스의 루트. 부모가 죽은 고아 프로세스를 입양한다
  • pageout (pid=2): 가상 메모리의 페이지 캐시를 담당
  • fsflush (pid=3): 파일 시스템의 버퍼 캐시를 관리

fork()와 exec()

  • 자식은 생성될 때 부모의 복제이다.
  • 자식에 새 프로그램이 로드된다 — exec, execvp

UNIX에서의 프로세스 생성:
1. fork() 시스템 콜로 새 프로세스 생성 → 부모의 완전한 복사본
2. exec() 시스템 콜로 프로세스의 메모리 공간을 새 프로그램으로 교체

부모 프로세스 (bash)
      │
   fork() ──────→ 자식 프로세스 (bash의 복사본)
      │                    │
      │                 exec("ls")
      │                    │
      │              자식 프로세스 (ls 프로그램으로 변환됨)
      │                    │
   wait()              exit()
      │◄───────────────────┘
    (계속)

프로세스 종료 (Process Termination)

정상 종료

  • 프로세스가 마지막 문장을 실행하고 OS에 삭제를 요청한다 (exit).
    • 자식에서 부모로의 출력 데이터는 wait를 통해 전달된다.
  • 열린 파일, 할당된 메모리, I/O 버퍼 등 프로세스의 자원은 OS가 회수(deallocate)한다.
int main()
{
    pid_t pid;
    pid = fork();              // 자식 프로세스 생성
    
    if (pid == 0) {            // ← 자식 프로세스 (fork()가 0을 반환)
        fd = open("/tmp/a.txt", O_READ);
        if (fd < 0) exit(-1);  // 파일 열기 실패 시 종료
        if (read(fd, pBuf, 100) < 0)
            exit(-2);          // 읽기 실패 시 종료
        printf("Hello, world\n");
        exit(0);               // 정상 종료
    }
    else {                     // ← 부모 프로세스 (fork()가 자식의 PID를 반환)
        pid = wait(&state);    // 자식이 종료할 때까지 대기
        printf("Parent: child %d, state:%d\n", pid, state);
        exit(0);
    }
}

흐름:
1. fork()로 자식 프로세스 생성
2. 자식(pid==0): 파일을 열고, 읽고, "Hello, world" 출력 후 exit(0)
3. 부모(pid>0): wait(&state)로 자식의 종료를 기다림
4. 자식이 종료하면 부모가 종료 상태를 받아 출력

강제 종료 (abort)

  • 부모가 자식 프로세스의 실행을 종료시킬 수 있다 (abort).
  • 종료 사유:
    • 자식이 할당된 자원을 초과한 경우
    • 자식에 할당된 자원이 더 이상 필요하지 않은 경우
    • 부모가 종료하는 경우 → 연쇄 종료(cascading termination): 부모 종료 시 모든 자식도 종료

좀비 프로세스 (Zombie Processes)

  • Zombie processes (Unix/Linux)

    • 프로세스가 종료되면, 부모가 wait 시스템 콜을 호출하여 정리할 때까지 좀비 상태로 남는다.
    • 이 상태에서는 프로세스 엔트리, 종료 상태, 자원 사용 정보를 제외한 모든 자원이 제거된다. 열린 파일, 할당된 메모리 등은 정리된다.
  • 부모가 자식보다 먼저 죽으면, init 프로세스가 자식을 상속한다.

핵심 포인트: 좀비 프로세스는 종료되었지만 부모가 wait()로 회수하지 않은 프로세스이다. 좀비가 많이 쌓이면 프로세스 테이블이 가득 차서 새 프로세스를 만들 수 없게 된다. 고아 프로세스는 init이 입양하여 정리한다.


협력 프로세스 (Cooperating Processes)

독립 프로세스 vs 협력 프로세스

유형설명
Independent process다른 프로세스의 실행에 영향을 주거나 받을 수 없다
Cooperating process다른 프로세스의 실행에 영향을 주거나 받을 수 있다

프로세스가 협력하는 이유

이유설명
정보 공유여러 프로세스가 같은 데이터에 접근
계산 속도 향상작업을 하위 작업으로 분할하여 병렬 실행
모듈성시스템 기능을 별도의 프로세스로 모듈화
편의성사용자가 여러 작업을 동시에 수행

계산 속도 향상

웹 서버 예시:

[단일 프로세스]              [협력 프로세스]
Process → Web server         Process → Encode ──→ I/O
(순차 처리)                  Process → Encode ──→ I/O
                             Process → Web server
                             (병렬 처리 → 속도 향상)
  • 특정 작업을 더 빠르게 실행하려면, 작업을 하위 작업(subtask)으로 분할하고 각각을 다른 작업들과 병렬(parallel)로 실행해야 한다.

프로세스 간 통신 (IPC: Interprocess Communication)

정의

  • 프로세스가 협력 프로세스와 소통하는 메커니즘

두 가지 기본 모델

모델설명방식
Shared memory협력 프로세스가 공유하는 메모리 영역프로세스들이 같은 메모리 영역을 직접 읽고 쓴다
Message system공유 변수에 의존하지 않고 프로세스 간 통신메시지를 send/receive하여 데이터를 교환한다

공유 메모리 (Shared Memory) 상세

  • 프로세스가 공유 메모리 시스템 콜을 통해 다른 프로세스의 주소 공간에 접근할 수 있다.
  • 과정:
    - 1. 한 프로세스가 공유 메모리 세그먼트를 생성한다.
    - 2. 다른 프로세스가 그 세그먼트를 자신의 주소 공간에 부착(attach)한다.
    - 3. 이후 두 프로세스가 같은 메모리 영역을 읽고 쓸 수 있다.

메시지 전달 (Message Passing)

메시지 전달의 특징

  • 같은 주소 공간을 공유하지 않고 프로세스가 통신하고 동작을 동기화할 수 있게 한다.
  • 통신하는 프로세스가 다른 컴퓨터에 있을 수 있는 분산 환경에 적합하다.

두 가지 통신 방식

직접 통신 (Direct Communication)

  • 프로세스가 서로를 명시적으로 지명해야 한다.
send(P, message)    ← 프로세스 P에게 메시지를 보낸다
receive(Q, message) ← 프로세스 Q로부터 메시지를 받는다
특성설명
링크가 자동으로 설정됨두 프로세스가 서로를 알면 바로 통신 가능
한 쌍에 정확히 하나의 링크두 프로세스 사이에 하나의 채널만 존재
보통 양방향양쪽 모두 보내고 받을 수 있다

단점 (hard coding): 프로세스 식별자를 직접 지정하므로, 종료된 프로세스의 ID가 재사용되면 엉뚱한 프로세스와 통신할 수 있다.


간접 통신 (Indirect Communication)


  • 메시지가 메일박스(포트라고도 함)를 통해 보내지고 받아진다.
send(A, message)    ← 메일박스 A에 메시지를 보낸다
receive(A, message) ← 메일박스 A에서 메시지를 받는다
특성설명
메일박스에 고유 ID가 있음각 메일박스는 유일한 식별자를 가진다
공통 메일박스를 공유해야 통신 가능같은 메일박스를 아는 프로세스만 통신
여러 프로세스가 하나의 링크에 연관 가능메일박스 하나에 여러 프로세스가 연결

메일박스 공유 문제

  • P1이 메일박스 A에 메시지를 보내고, P2와 P3가 모두 A에서 receive하면 — 누가 메시지를 받는가?
  • 해결책: (1) 링크를 최대 2개 프로세스로 제한, (2) 한 번에 하나의 프로세스만 receive 실행 허용, (3) 시스템이 수신자를 임의로 선택

POSIX 메시지 큐 예제 (Example: POSIX Message Queue)

코드 분석

Process 1 (송신자):

#define KEY 100
struct mymesg { long mtype; char mtext[512]; };

int main(void) {
    struct mymesg msg;
    msgqId = msgget(KEY, S_IRUSR|S_IWUSR);  // KEY=100으로 메시지 큐 생성/열기
    msg.mtype = 3;                            // 메시지 타입을 3으로 지정
    strcpy(msg.mtext, "Writing to message queue");
    msgsnd(msgqId, &msg, sizeof(msg), 0);     // 메시지 전송
    return 0;
}

Process 2 (수신자):

#define KEY 100

int main(void) {
    char* pMem = NULL;
    msgqId = msgget(KEY, S_IRUSR|S_IWUSR);  // 같은 KEY=100으로 메시지 큐 열기
    msgrcv(msgqId, pBuf, 512, 3, 0);          // 타입 3인 메시지를 수신
    printf("%s", pMem);
    return 0;
}

핵심 함수 설명:

함수한국어설명
msgget(KEY, ...)메시지 큐 생성/열기KEY 값으로 메시지 큐를 식별. 없으면 생성, 있으면 열기
msgsnd(id, msg, size, 0)메시지 전송지정된 큐에 메시지를 보낸다
msgrcv(id, buf, size, 3, 0)메시지 수신지정된 큐에서 타입 3인 메시지를 받는다

메시지 큐 내부 구조

  • 메시지 큐는 커널 공간에 존재한다.
  • msgsnd()로 메시지를 보내면 사용자 공간의 데이터가 커널의 큐로 복사(copy)된다.
  • msgrcv()로 메시지를 받으면 커널의 큐에서 사용자 공간으로 복사된다.
  • type 필드로 메시지를 선택적으로 수신할 수 있다 (타입 3만 받기 등).

통신 모델 (Communications Models)

두 가지 모델 비교 그림

(a) 메시지 전달 (Message Passing)

┌────────────┐
│ process A  │ M ──┐
│            │     │  1: send
├────────────┤     │
│ process B  │ M   │
│            │     │  2: receive
├────────────┤     │
│            │     │
│  kernel    │ M ◄─┘  ← 커널을 통해 전달
└────────────┘
  • 메시지가 커널을 거쳐 전달된다 (시스템 콜 2번: send + receive).

(b) 공유 메모리 (Shared Memory)

┌────────────┐
│ process A  │     1: write
│     ┌──────┤ ◄──┐
│-----│shared│    │
│     └──────┤    │  ← 공유 영역에 직접 읽고 쓴다
│ process B  │ ◄──┘ 2: read
├────────────┤
│  kernel    │     ← 커널 개입 최소 (설정 시에만)
└────────────┘
  • 공유 메모리 영역을 설정한 후에는 커널 개입 없이 직접 읽고 쓴다.
비교 항목메시지 전달공유 메모리
커널 개입매번 (send/receive마다)설정 시에만 (이후 직접 접근)
속도상대적으로 느림 (복사 오버헤드)상대적으로 빠름 (직접 접근)
분산 환경적합 (네트워크를 통해 가능)부적합 (같은 머신에서만)
동기화내장 (send/receive 자체가 동기화)별도 필요 (세마포어 등)
구현 난이도쉬움어려움 (동기화 필요)

동기화 (Synchronization)

블로킹 vs 비블로킹

유형방식설명
Blocking send메시지가 수신될 때까지, 또는 큐가 가득 차면 송신자가 차단보낸 메시지가 확실히 전달될 때까지 기다린다
Blocking receive메시지가 도착할 때까지 수신자가 차단메시지가 올 때까지 기다린다
Non-blocking send송신자가 메시지를 보내고 계속 진행전달 여부와 관계없이 바로 다음 작업 수행
Non-blocking receive수신자가 유효한 메시지 또는 null을 받음메시지가 없으면 null을 받고 계속 진행
  • Blocking = Synchronous (동기식): 상대방의 응답을 기다린다
  • Non-blocking = Asynchronous (비동기식): 기다리지 않고 바로 진행한다

버퍼링 (Buffering)

  • 링크에 부착된 메시지 큐

3가지 구현 방식

방식원문한국어동작
Zero capacity0 messages. Sender must wait for receiver (rendezvous)용량 0. 송신자가 수신자를 기다려야 한다 (랑데뷰)큐가 없으므로 송신자와 수신자가 동시에 만나야 전달 가능
Bounded capacityFinite length of n messages. Sender must wait if link full유한 용량 n개. 링크가 가득 차면 송신자가 대기최대 n개까지 메시지 저장 가능. 가득 차면 송신자가 차단됨
Unbounded capacityInfinite length. Sender never waits무한 용량. 송신자가 절대 대기하지 않음이론적으로 무한한 메시지를 저장 (실제로는 메모리 한계 존재)

핵심 포인트: 랑데뷰(zero capacity)는 가장 강한 동기화를 제공하지만 성능이 낮고, 무한 버퍼(unbounded)는 가장 유연하지만 메모리 문제가 발생할 수 있다. 실제 시스템은 대부분 bounded capacity를 사용한다.


전체 핵심 용어 정리 (Key Terms)

Key Terms설명
Program디스크에 저장된 정적 코드 (수동적 개체)
Process실행 중인 프로그램 (능동적 개체)
PCB (Process Control Block)프로세스의 모든 상태 정보를 담는 커널 자료구조
PID (Process ID)각 프로세스를 구분하는 고유 번호
Text / Code프로그램의 기계어 코드가 저장되는 메모리 영역
Data section전역 변수/정적 변수가 저장되는 영역
BSS초기화되지 않은 전역 변수 영역 (Block Started by Symbol)
Heap동적 메모리 할당(malloc/new) 영역 (↑ 성장)
Stack함수 호출 시 지역변수/리턴주소 저장 (↓ 성장)
Context Switch현재 프로세스의 PCB 저장 + 새 프로세스의 PCB 로드
Ready QueueCPU 할당을 기다리는 프로세스들의 큐
Device QueueI/O 장치를 기다리는 프로세스들의 큐
Long-term Scheduler디스크 → 메모리로 프로세스 로드 결정
Short-term SchedulerCPU에 실행할 프로세스 선택
fork()자식 프로세스를 생성하는 UNIX 시스템 콜
exec()프로세스 메모리를 새 프로그램으로 교체하는 시스템 콜
exit()프로세스를 종료하는 시스템 콜
wait()자식 프로세스 종료를 기다리는 시스템 콜
Zombie Process종료되었지만 부모가 wait()하지 않아 잔류하는 프로세스
Orphan Process부모가 먼저 종료된 프로세스 (init이 입양)
Cascading Termination부모 종료 시 모든 자식도 종료
IPC프로세스 사이의 데이터 교환 메커니즘
Shared Memory프로세스들이 공유하는 메모리 영역을 통한 IPC
Message Passingsend/receive로 메시지를 교환하는 IPC
Direct Communication프로세스를 명시적으로 지명하여 통신
Indirect Communication메일박스(포트)를 통한 통신
Mailbox / Port간접 통신에서 메시지가 저장/인출되는 추상 객체
Blocking (Synchronous)상대방의 응답을 기다림
Non-blocking (Asynchronous)기다리지 않고 바로 진행
Rendezvous버퍼 없이 송신자와 수신자가 동시에 만나는 방식
Bounded Capacity큐에 최대 n개까지 메시지 저장 가능
TLB (Translation Lookaside Buffer)가상→물리 주소 변환을 캐싱하는 하드웨어
profile
effort is indispensable but choice is gift

0개의 댓글