반응형

이전에 면접 준비하며 준비했던 내용 공유합니다

 

운영체제 기본 개념

1. 하드웨어 (Hardware)

  • 중앙 처리 장치(CPU): 명령어 해석 및 실행.
  • 메모리(Memory): 프로그램과 데이터를 저장.
  • 입출력 장치(I/O devices): 사용자와 시스템 간 데이터 교환.

1. 부트스트랩 (Bootstrap)

  • 저장 위치: ROM(Read-Only Memory)에 저장.
  • 역할:
    1. 시스템 전원이 켜지면 실행됨.
    2. 운영체제의 커널(kernel) 을 찾아 주 메모리(RAM) 에 적재.
  • 결과: 커널이 실행되면서 시스템 초기화가 진행됨.

2. 커널과 시스템 프로세스

  • 커널(Kernel): 운영체제의 핵심 부분, 자원 관리와 제어 담당.
  • 시스템 프로세스 / 시스템 데몬(Daemon):
    • 커널 수행 중 계속 동작.
    • 백그라운드에서 시스템 기능(예: 스케줄링, 로그 관리, 네트워크 서비스 등)을 지원.

3. 주 메모리 (RAM)

  • 특징: 재기록 가능한 메모리.
  • 용도:
    • 실행 중인 프로그램과 데이터를 저장.
    • CPU가 직접 접근 가능.
    • 전원이 꺼지면 내용이 사라지는 휘발성 메모리.

4. 컴퓨터 구조

(1) 폰 노이만 구조 (Von Neumann Architecture)

  • 명령어와 데이터를 같은 버스(경로)를 통해 전달.
  • 특징: 구조 단순, 범용 컴퓨터에 널리 사용.
  • 단점: 명령어와 데이터가 한 버스를 공유해 병목 현상(폰 노이만 병목) 발생 가능.

(2) 하버드 아키텍처 (Harvard Architecture)

  • 명령어와 데이터를 서로 다른 버스에서 전달.
  • 특징: 명령어 읽기와 데이터 접근을 동시에 수행 가능 → 병목 최소화.
  • 주로 임베디드 시스템, DSP(Digital Signal Processor) 등에서 사용.

5. 입출력 구조 (I/O Structure)

1) 인터럽트 기반 I/O (Interrupt-Driven I/O)

  • 동작 방식:
    • CPU가 I/O 장치에 작업을 지시하고 다른 일을 수행.
    • I/O 장치가 작업을 끝내면 인터럽트(Interrupt) 신호를 CPU에 보냄.
    • CPU는 인터럽트 서비스 루틴(ISR)을 실행하여 결과를 처리.
  • 장점: CPU가 불필요하게 대기하지 않음.
  • 단점: 인터럽트가 자주 발생하면 오버헤드 증가.

2) 직접 메모리 접근 (DMA, Direct Memory Access)

  • 동작 방식:
    • CPU가 I/O 장치에 메모리 전송을 직접 하지 않고, DMA 컨트롤러에게 위임.
    • DMA 컨트롤러가 메모리와 I/O 장치 간 데이터를 직접 전송.
    • 전송이 완료되면 CPU에 인터럽트를 보내 알림.
  • 장점: CPU 개입 최소화 → 고속 데이터 전송 가능 (예: 디스크 ↔ 메모리).
  • 활용: 대량 데이터 전송이 필요한 경우 (예: 영상, 네트워크, 디스크 입출력).

2. 운영체제 (Operating System, OS)

  • 목적: 사용자가 시스템을 쉽게 사용할 수 있도록 설계.
  • 특징:
    • 자원 사용 자체에는 신경 쓰지 않음.
    • 자원 할당자(Resource Allocator): CPU, 메모리, I/O 자원들을 적절히 배분.
    • 제어 프로그램(Control Program): 프로그램 실행과 하드웨어 동작을 제어.
    메모리에 적재되어 있고, 실행되는 프로그램을 “프로세스”라 부름1. 인터럽트(Interrupt)
    • 발생 원인: CPU 외부의 하드웨어 장치가 CPU에게 서비스를 요청할 때 발생
    • 예: 키보드 입력, 디스크 I/O 완료, 네트워크 패킷 도착
    • 특징
      • 비동기적으로 발생 (CPU가 어떤 명령을 실행 중이든 외부 장치에서 신호를 보냄)
      • CPU는 현재 실행 중이던 명령을 끝내고 인터럽트 서비스 루틴(ISR)으로 점프
      • 주로 외부 이벤트 처리를 위해 사용
    • 예시:
      • 키보드에서 키가 눌림 → 인터럽트 발생 → 운영체제 커널이 입력 버퍼에 저장

    2. 트랩(Trap, 예외 Exception)
    • 발생 원인: CPU 내부에서 실행 중인 프로그램이 원인이 되는 상황
    • 예: 0으로 나누기, 잘못된 메모리 접근, 시스템 콜 호출
    • 특징
      • 동기적으로 발생 (특정 명령 실행 결과로 즉시 발생)
      • 크게 두 종류로 나뉨:
        1. 예외(Exception): 오류 상황 (Divide by zero, Page fault 등)
        2. 트랩(Trap, 소프트웨어 인터럽트): 의도적으로 발생시켜 운영체제 서비스 호출 (System call)
    • 예시:
      • int 0x80 (리눅스 시스템 콜) → 커널로 진입
      • 잘못된 포인터 접근 → Segmentation fault

    3. 차이점 요약구분 인터럽트(Interrupt) 트랩 / 예외(Trap, Exception)
    발생 원인 하드웨어 장치 (외부) CPU 내부 명령 실행 결과 (소프트웨어)
    발생 시점 비동기적 (언제든 발생 가능) 동기적 (명령 실행 직후 발생)
    주 용도 외부 이벤트 처리 오류 처리, 운영체제 서비스 호출
    예시 키보드 입력, 디스크 I/O 완료 0 나누기, 페이지 폴트, 시스템 콜

    👉 정리하면,
    • 인터럽트는 외부 장치가 CPU를 부르는 "하드웨어 호출"
    • 트랩/예외는 프로그램 실행 도중 CPU 내부에서 발생하는 "소프트웨어 호출/오류"
    이중 연산모드
    • CPU 내부에 모드 비트(Mode Bit) 라는 플래그가 있음.
    • 1 → 사용자 모드(User Mode)
    • 0 → 커널 모드(Kernel Mode, Supervisor Mode)

    2. 사용자 모드 (User Mode)
    • 일반 응용 프로그램이 동작하는 모드
    • 제한된 명령어만 실행 가능
      • 입출력(I/O) 명령, 메모리 보호를 무시하는 명령 등은 금지
    • 잘못된 동작이 발생하면 **트랩(예외)**을 발생시켜 운영체제가 처리

    3. 커널 모드 (Kernel Mode)
    • 운영체제(OS) 커널이 실행되는 모드
    • 모든 명령어 실행 가능 (특권 명령 포함)
      • 입출력 제어, 타이머 관리, 메모리 관리, 인터럽트 제어 등
    • 시스템 전체에 영향을 줄 수 있는 연산은 커널 모드에서만 수행

    4. 모드 전환
    • 부팅 시: 항상 커널 모드에서 시작 (운영체제가 제어권을 가짐)
    • 시스템 콜, 트랩, 인터럽트 발생 시: 하드웨어가 자동으로 커널 모드로 전환
    • 커널이 작업을 마친 후: 다시 사용자 모드로 전환하여 응용 프로그램 실행

    5. 이중 모드 운영의 목적
    • 보호(Protection): 사용자 프로그램이 임의로 하드웨어 자원(I/O, 메모리 등)을 제어하지 못하게 막음
    • 안정성(Stability): 오류가 발생해도 운영체제가 제어권을 가짐 → 시스템 전체가 멈추는 것 방지
    • 보안(Security): 악의적인 프로그램이 커널 수준 권한을 직접 사용하는 것을 차단
    운영체제의 메모리 관리
    1. 메모리 사용량 추적, 누구에 의해 사용되고 있는지
    2. 어떤 프로세스를 적재하고 제거할 것인지
    3. 필요에 따라 메모리 공간을 할당하고 회수
  • 1. 모드 비트 (Mode Bit)
  • 현재의 운영체제는 인터럽트 구동식이다

3. 응용 프로그램 (Application Programs)

  • 사용자 요구를 직접 해결하는 소프트웨어.
  • 예시: 워드 프로세서, 웹 브라우저 등.

4. 사용자 (Users)

  • 응용 프로그램을 활용해 컴퓨터를 사용하는 주체.

👉 요약하면, 하드웨어가 기본 자원, 운영체제가 이를 관리, 응용 프로그램이 사용자 목적을 달성, 그리고 사용자가 최종적으로 시스템을 활용하는 구조입니다.


운영체제 서비스

운영체제 서비스 (Operating System Services)

운영체제는 사용자와 하드웨어 사이에서 여러 **서비스(services)**를 제공하여 편의성, 효율성, 보안성을 보장합니다.


1. 사용자 인터페이스 제공 (User Interface)

  • CLI(Command Line Interface): 터미널 기반 명령어 입력 (예: Bash, PowerShell)
  • GUI(Graphical User Interface): 아이콘/윈도우 기반 그래픽 환경 (예: Windows, macOS)
  • 터치 인터페이스: 모바일 OS에서 활용

2. 프로그램 수행 (Program Execution)

  • 프로그램을 메모리에 적재하고 실행
  • 실행 중인 프로그램의 중단, 재개, 종료 기능 제공
  • 예: fork(), exec() 시스템 콜

3. 입출력 연산 (I/O Operations)

  • 사용자 프로그램은 직접 장치 제어 불가 → OS가 대신 수행
  • 키보드 입력, 디스크 읽기/쓰기, 네트워크 송수신 등
  • 장치 드라이버를 통해 하드웨어 추상화

4. 파일 시스템 조작 (File-System Manipulation)

  • 파일 생성, 삭제, 읽기/쓰기, 접근 권한 제어
  • 디렉토리 구조 관리
  • 예: open(), read(), write(), close() 시스템 콜

5. 통신 (Communication)

  • 프로세스 간 통신(IPC, Inter-Process Communication) 기능 제공
  • 공유 메모리(shared memory): 동일 메모리 영역에 접근
  • 메시지 전달(message passing): 커널을 통해 메시지 송수신
  • 예: 파이프(pipe), 소켓(socket), 큐(queue)

6. 오류 탐지 (Error Detection)

  • CPU, 메모리, I/O 장치 동작 중 발생하는 오류 감지 및 처리
  • 잘못된 명령 실행, 메모리 접근 위반(segmentation fault), 디스크 읽기 오류 등
  • 오류 발생 시 트랩을 발생시켜 운영체제가 개입

7. 자원 할당 (Resource Allocation)

  • CPU 시간, 메모리, I/O 장치, 파일 등 한정된 자원을 효율적으로 분배
  • 스케줄링(scheduling) 기법 활용 (FCFS, RR, Priority 등)

📌 정리

운영체제 서비스는 크게 **사용자 편의를 위한 서비스(UI, 실행, I/O, 파일, 통신)**와 **시스템 보호 및 효율성을 위한 서비스(오류 탐지, 자원 할당)**로 나눌 수 있습니다.

System Call (시스템 콜)

  • 정의: 사용자 프로그램이 운영체제의 커널이 제공하는 기능(입출력, 프로세스 제어, 메모리 관리 등)을 요청하는 인터페이스
  • 역할: 사용자 모드 → 커널 모드로 안전하게 전환하여 특권 명령 실행 가능하게 해줌
  • 예시
    • read(), write(), open(), close() (파일 조작)
    • fork(), exec(), wait() (프로세스 관리)
    • socket(), connect(), send(), recv() (통신)

2. API (응용 프로그래밍 인터페이스)

  • 정의: 응용 프로그램이 운영체제, 라이브러리, 프레임워크 기능을 쉽게 사용하도록 만든 함수/메서드 집합
  • 역할: 프로그래머가 직접 system call을 다루지 않고, 고수준 함수 호출로 편리하게 접근할 수 있게 함
  • 예시
    • C의 stdio.h 라이브러리 → 내부적으로 read()/write() 시스템 콜 호출
    • Java의 FileInputStream → OS의 파일 입출력 system call 사용

3. 관계

  • System Call: 운영체제 커널 기능에 직접 접근하는 인터페이스
  • API: 응용 프로그램이 쉽게 사용할 수 있도록 제공되는 함수 인터페이스 (보통 system call을 내부적으로 호출)

👉 즉,

  • API는 프로그래머 친화적인 인터페이스
  • System Call은 운영체제 친화적인 인터페이스

통신(IPC)

메세지 전달, 공유 메모리

1. 메시지 전달 (Message Passing)

  • 개념: 프로세스들이 커널(운영체제)을 매개로 하여 메시지를 주고받음
  • 방식
    • send(destination, message)
    • receive(source, message)
  • 특징
    • 프로세스 간에 메모리를 공유하지 않음
    • 분산 시스템에서도 사용 가능 (네트워크 기반 통신)
  • 장점: 단순하고, 프로세스 간 강한 독립성 보장
  • 단점: 커널 개입이 필요해 속도가 느릴 수 있음
  • 예시: 파이프(pipe), 소켓(socket), 메시지 큐(message queue)

2. 공유 메모리 (Shared Memory)

  • 개념: 운영체제가 특정 메모리 영역을 여러 프로세스가 공동으로 접근할 수 있도록 허용
  • 특징
    • 한 번 설정되면 커널 개입 없이 메모리 접근 가능
    • 가장 빠른 IPC 방식
  • 주의점: 동시에 접근할 때 데이터가 꼬이지 않도록 동기화 기법 필요 (세마포어, 뮤텍스)
  • 예시: POSIX shared memory (shm_open, mmap)

3. 비교 정리

구분 메시지 전달 (Message Passing) 공유 메모리 (Shared Memory)

데이터 교환 방식 커널을 통해 메시지 송수신 특정 메모리 영역을 공동 사용
속도 상대적으로 느림 (커널 개입 필요) 빠름 (직접 메모리 접근)
독립성 프로세스 간 강한 독립성 유지 프로세스 간 결합도 높음
동기화 필요성 커널이 동기화 보장 개발자가 직접 동기화 관리 필요
활용 예시 파이프, 소켓, 메시지 큐 shm, mmap, DB 공유 메모리 캐시

정리

  • 메시지 전달: 운영체제 커널을 통해 안전하게 통신, 하지만 속도는 느림.
  • 공유 메모리: 속도가 빠르지만 동기화 문제 해결을 개발자가 직접 해야 함.

프로세스

 

메모리에서 적재되어 실행중인 프로그램

작업을 할당받는 단위

  • 프로세스(Process): 실행 중인 프로그램. 자원(메모리 공간, 파일, 핸들 등)을 할당받는 단위
  • → 커널이 PCB(Process Control Block)로 관리: PID, 상태, 스케줄링 정보, 메모리 정보(페이지 테이블), 열려 있는 파일 등.
  • 스레드(Thread): 프로세스 안의 실행 흐름. CPU 스케줄링의 단위
  • → 각 스레드는 **자신만의 스택, 레지스터 집합, 프로그램 카운터(PC)**를 갖고, 코드·데이터·힙은 프로세스 내 다른 스레드와 공유.

프로세스의 전형적 메모리 구역(가상 메모리 레이아웃)

아래 순서는 보통의 개념도(낮은 주소 → 높은 주소)입니다.

  1. 텍스트(코드) 섹션 (text / code)
  • 기계어 명령이 저장되는 구역 (보통 읽기 전용, 공유 가능)
  • 여러 프로세스가 같은 실행 파일을 돌릴 때 코드 페이지를 공유해 메모리 절약 가능
  1. 데이터 섹션 (data)
  • 초기값이 있는 전역/정적 변수가 위치 (예: int g = 10;)
  • 프로세스마다 개별 복사본을 가짐(스레드 간 공유)
  1. BSS 섹션 (bss)
  • 초기값이 없는 전역/정적 변수 (예: int g2;)
  • 로더가 0으로 초기화하여 시작
  1. 힙(Heap)
  • 동적 할당 영역 (malloc/free, new/delete)
  • 런타임에 필요해질수록 “위로”(주소 증가 방향) 확장되는 것이 관례
  • 여러 스레드가 공유 → 동시성 안전을 위해 할당기 내부에 락/아레나 등 활용
  1. 스택(Stack)
  • 함수 호출 프레임이 쌓이는 영역: 복귀 주소, 매개변수, 지역변수, 저장된 레지스터
  • 일반적으로 “아래로”(주소 감소 방향) 성장
  • 스레드마다 독립 스택을 가짐 (스택 크기는 생성 시 정해지는 경우가 많음)
  1. (플랫폼에 따라) mmap/공유 라이브러리 영역
  • mmap, 공유 객체(.so/.dll) 등이 매핑되는 가변 영역

개념도 (단순화)

낮은 주소
[ 텍스트 ] → [ 데이터 ] → [ BSS ] → [ 힙 ↑ ] … [ mmap 등 ] … [ ↓ 스택 ]
높은 주소

프로그램 카운터(PC, Instruction Pointer)

  • 다음에 실행할 명령의 주소를 가리키는 레지스터.
  • 스레드마다 하나씩 존재(컨텍스트 스위치 시 PC/레지스터 저장·복원).
  • 함수 호출 시: 호출 명령이 복귀 주소를 스택에 저장, PC는 호출 대상 주소로 변경 → ret 시 스택의 복귀 주소로 PC 복원.

스택 자세히

  • 포함 내용:
  • 복귀 주소(return address), 매개변수(arguments), 지역변수, 저장된 레지스터(예: 프레임 포인터/링크 레지스터)
  • 단위: 스택 프레임(함수 호출 1회에 해당)
  • 특징/주의:
    • Stack Overflow: 너무 깊은 재귀, 큰 지역배열 등으로 보호 페이지 침범
    • 스택은 매우 빠름(연속 메모리 + 단순 푸시/팝) / 수명은 블록/스코프에 종속

힙 자세히

  • 동적 수명: 필요할 때 할당(allocate), 더 이상 필요 없으면 해제(free)
  • 특징/주의:
    • 메모리 누수(Leak): 해제를 잊으면 장기 실행 시 문제
    • Double Free / Use-After-Free: 이미 해제한 블록 재사용 → 치명적 버그
    • Fragmentation: 조각화로 인한 큰 블록 할당 실패 가능
    • 멀티스레드 환경: 동시성 이슈(락 경합, 캐시 라인 경합 등) → 현대 할당기는 아레나/슬랩 등으로 완화

데이터 섹션 & BSS 요약

  • 데이터(data): 초기값 있는 전역/정적(실행 파일 안에 초기값 저장)
  • BSS: 초기값 없는 전역/정적(로더가 0으로 초기화)
  • 공통: 프로세스 단위로 소유(스레드들이 공유)

텍스트 섹션 요약

  • 실행 코드 저장
  • 보통 읽기 전용 + 실행 가능, 프로세스 간 공유 가능한 페이지로 매핑 돼 메모리 절약

1. 프로세스 상태 (Process States)

운영체제는 프로세스를 관리하기 위해 여러 상태로 구분합니다. 대표적인 상태는 다음과 같습니다:

  1. New (생성)
    • 프로세스가 생성되고 있는 상태
    • PCB가 만들어지고, OS가 메모리/자원 할당 준비
    • 아직 실행은 시작되지 않음
  2. Ready (준비완료)
    • 실행할 준비가 끝났지만 CPU를 배정받지 못한 상태
    • 메모리와 필요한 자원은 확보 완료
    • 스케줄러가 CPU를 배정하면 곧 실행 상태로 전환됨
  3. Running (실행)
    • CPU를 점유하고 명령어를 수행 중인 상태
    • 단일 코어에서는 한 시점에 하나의 프로세스만 실행 가능
    • 실행 중 인터럽트나 시간 할당량 만료 시 다시 준비 상태로 전환
  4. Waiting (대기, Blocked)
    • I/O 요청, 이벤트 발생 대기 등으로 CPU가 아닌 외부 조건을 기다리는 상태
    • 예: 디스크 입출력 완료, 사용자 입력 등
    • 조건이 만족되면 준비 상태로 전환됨
  5. Terminated (종료)
    • 프로세스 실행이 끝난 상태
    • PCB와 자원이 정리(해제)됨

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

운영체제가 프로세스를 관리하기 위해 유지하는 핵심 데이터 구조.

각 프로세스마다 PCB가 1개씩 존재하며, 프로세스의 “신분증/이력카드” 같은 역할을 함.

PCB에 포함되는 정보

  1. 프로세스 상태
    • New, Ready, Running, Waiting, Terminated 중 현재 상태
  2. 프로그램 카운터 (Program Counter, PC)
    • 다음 실행할 명령어의 주소 저장
  3. CPU 레지스터 정보
    • 범용 레지스터, 스택 포인터, PSW(Program Status Word) 등
    • 컨텍스트 스위칭 시 저장/복원되어 실행 재개 가능
  4. 스케줄링 정보
    • 우선순위, 스케줄링 큐 포인터, CPU 사용 시간 등
  5. 메모리 관리 정보
    • 페이지 테이블, 세그먼트 테이블, 메모리 경계 레지스터 등
    • 해당 프로세스가 접근 가능한 메모리 영역 기록
  6. 계정 및 자원 정보
    • 파일 핸들, 입출력 장치 상태, 소유자 ID, 사용 권한 등

3. 정리 그림 (흐름도)

프로세스 상태 전이 예시

   [New]
     ↓
   [Ready] ← (I/O 완료) ← [Waiting]
     ↓ ↑
  (스케줄링)   (시간 종료/인터럽트)
     ↓ ↑
   [Running]
     ↓
  [Terminated]


👉 요약:

  • 프로세스 상태는 생성 → 준비 → 실행 → 대기/종료로 전이되며, CPU·I/O 스케줄링에 따라 바뀜.
  • PCB는 프로세스의 모든 관리 정보를 담는 자료구조로, 컨텍스트 스위칭스케줄링에 필수적임.

쓰레드

작업을 실행하는 단위

프로세스 안의 실행 흐름.

CPU 스케줄링의 단위

→ 각 스레드는 **자신만의 스택, 레지스터 집합, 프로그램 카운터(PC)**를 갖고,

코드·데이터·힙은 프로세스 내 다른 스레드와 공유

TCB(Thread Control Block)에 포함되는 정보

스레드별로 필요한 최소 정보만 따로 가짐:

  • 스레드 ID (TID)
  • 프로그램 카운터(PC): 다음 실행할 명령어
  • 레지스터 집합: 현재 CPU 레지스터 상태
  • 스택 포인터: 각 스레드는 자기만의 스택을 가짐
  • 스케줄링 정보: 우선순위, 상태(Running, Ready, Waiting 등)
  • (운영체제에 따라) 신호 처리 정보, TLS(Thread-Local Storage) 등

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

운영체제는 동시에 여러 프로세스가 실행되는 환경에서, CPU를 누구에게 줄 것인지를 결정해야 합니다.

이를 담당하는 것이 **프로세스 스케줄러(Process Scheduler)**입니다.

  • 목표:
    • CPU 및 시스템 자원의 효율적 활용
    • 사용자에게 빠른 응답 제공 (대화형 시스템)
    • 공평성과 우선순위 보장
  • 잡 큐(Job Queue):
    • 시스템에 들어온 모든 프로세스가 대기하는 큐
    • 여기서 스케줄러가 선택해 실행 대기열(Ready Queue)로 보냄

2. 스케줄러의 종류

(1) 장기 스케줄러 (Long-Term Scheduler, Job Scheduler)

  • 역할: 어떤 프로세스를 메모리에 올려 실행할지 결정
  • 특징:
    • 실행할 **잡 큐(Job Pool)**에서 프로세스를 선택 → 메모리 적재
    • 실행 프로세스의 전체 수를 제어하여 CPU와 I/O의 균형 유지
  • 효과:
    • 입출력 중심 프로세스CPU 중심 프로세스를 적절히 혼합하여 자원 활용 극대화
  • 예시: 배치 시스템(batch system)에서 주로 사용됨
  • 현대의 시분할 시스템에서는 장기 스케줄러가 거의 사용되지 않음 (대부분 시스템이 자동으로 처리)

(2) 단기 스케줄러 (Short-Term Scheduler, CPU Scheduler)

  • 역할: **실행 준비(Ready Queue)**에 있는 프로세스 중, 누구에게 CPU를 줄지 결정
  • 실행 시점: 매우 짧은 시간 단위로 동작 (ms 단위)
  • 효과: 시스템 반응성과 CPU 활용률에 직접적 영향
  • 프로세스 특성 고려:
    • 입출력 중심 프로세스(I/O-bound process)
      • CPU는 짧게 쓰고, I/O 요청이 잦음
      • 빨리 실행해서 I/O 장치가 놀지 않도록 해주는 것이 중요
    • CPU 중심 프로세스(CPU-bound process)
      • 계산 위주, CPU를 오래 사용
      • I/O 요청이 적음
    • ⇒ 두 종류를 적절히 섞어야 전체 자원 활용이 좋아짐

(3) 중기 스케줄러 (Medium-Term Scheduler) – 선택적

  • 역할: 프로세스 실행을 일시 중단(suspend) → 메모리에서 내보냈다가 → 나중에 복귀
  • 이 과정을 **스와핑(Swapping)**이라 함
  • 효과:
    • 메모리 부족 시 부하를 줄이고, 다중 프로그래밍 정도를 제어
    • 우선순위 있는 프로세스가 자원을 빨리 확보할 수 있게 함

3. 스와핑 (Swapping)

  • 정의: 프로세스를 **보조기억장치(디스크)**로 내보냈다가, 필요할 때 다시 메모리로 불러오는 과정
  • 특징:
    • 프로세스는 원래 실행되던 시점부터 재개됨 (PCB에 상태 저장)
    • 메모리 공간 확보 및 CPU 이용률 최적화
  • 장점: 메모리 관리 유연성 증가, 다중 프로그래밍 향상
  • 단점: 디스크 I/O 오버헤드 발생 → 잦으면 성능 저하

4. 정리 표

스케줄러 종류 동작 위치 역할 실행 빈도 주요 목적

장기 스케줄러 잡 큐 → 메모리 어떤 프로세스를 실행시킬지 선택 느림 (분/초 단위) CPU/IO 밸런스 유지, 다중 프로그래밍 정도 제어
단기 스케줄러 준비 큐 → CPU 다음 실행할 프로세스 선택 매우 빠름 (ms 단위) 응답속도 개선, CPU 활용 극대화
중기 스케줄러 메모리 ↔ 디스크 프로세스 일시 중단/재개 (스와핑) 상황에 따라 메모리 회수, 우선순위 관리

👉 요약:

  • 장기 스케줄러: 잡 큐에서 메모리로 올릴 프로세스 선택 (CPU vs I/O 균형).
  • 단기 스케줄러: Ready Queue에서 CPU를 줄 프로세스 선택 (밀리초 단위, 즉각적).
  • 중기 스케줄러: 메모리 ↔ 디스크로 스와핑, 부하 조절.

프로세스 생성 (Process Creation)

운영체제에서 새로운 프로세스가 생성될 때, 일반적으로 다음 단계가 일어납니다.

  1. 부모 프로세스(Parent Process)가 자식 프로세스(Child Process)를 생성
    • Unix 계열: fork() 시스템 콜 사용
    • Windows 계열: CreateProcess() API 사용
  2. 부모와 자식의 실행 관계
    • 병행 실행(Concurrent Execution): 부모는 계속 실행, 자식은 독립적으로 실행
    • 부모가 대기(Wait): 부모는 wait()를 호출하여 자식이 끝날 때까지 기다림
  3. 프로세스 주소 공간
    • 자식은 **부모의 복사본(Copy)**을 가짐 (코드, 데이터, 스택 등)
    • 하지만 별도의 PID(Process ID) 부여 → 독립된 실행 단위
    • 자식이 원하면 exec() 계열 호출로 새로운 프로그램을 덮어씀

2. 프로세스 종료와 관련 개념

(1) 정상 종료

  • 자식 프로세스가 exit() 호출 시 종료
  • 운영체제는 **종료 상태(exit status)**를 부모에게 전달
  • 부모는 wait()를 호출해 종료 상태를 회수 → 자식 PCB가 해제됨

(2) 좀비 프로세스 (Zombie Process)

  • 정의: 자식이 종료되었지만, 부모가 wait()를 호출하지 않아 PCB가 해제되지 않은 상태
  • 특징:
    • 실행은 끝났지만 PCB는 그대로 남음 → 프로세스 테이블에 기록 유지
    • 상태는 “Z” (Zombie)로 표시
    • 다수의 좀비가 생기면 프로세스 테이블 고갈 문제 발생

(3) 고아 프로세스 (Orphan Process)

  • 정의: 부모가 먼저 종료되어 부모가 없는 자식 프로세스
  • 처리 방법:
    • Unix 계열에서는 **init 프로세스(PID 1)**가 고아 프로세스를 자동으로 인수 → 정상적으로 실행/종료 가능
    • 따라서 고아 프로세스는 시스템에 큰 문제는 일으키지 않음

3. 그림으로 정리

부모 fork()
   ├─ 부모 계속 실행
   └─ 자식 프로세스 생성
         ├─ 부모와 병행 실행
         ├─ 부모가 wait() 호출 → 정상 회수
         ├─ 부모가 회수 안 함 → [좀비 프로세스]
         └─ 부모 먼저 종료 → [고아 프로세스]


✅ 요약:

  • 자식은 부모의 복사본으로 생성되지만, 독립된 PID를 가짐.
  • 부모와 자식은 병행 실행 가능, 또는 부모가 wait()로 자식 종료까지 대기 가능.
  • 좀비 프로세스: 자식 종료 후 부모가 회수하지 않음 → PCB만 남음.
  • 고아 프로세스: 부모가 먼저 종료 → init 프로세스가 대신 관리.

프로세스 간 통신(IPC, Inter-Process Communication)

  • 필요성:
    • 다중 프로세스 환경에서 데이터 교환, 동기화, 협력 수행을 위해 사용
    • OS는 안전성과 효율성을 위해 여러 가지 IPC 메커니즘을 제공

2. IPC 모델

(1) 공유 메모리 시스템 (Shared Memory)

  • 개념: 두 프로세스가 같은 메모리 영역을 공유하여 데이터를 주고받음
  • 특징:
    • 가장 빠른 통신 방법 (커널 개입 최소화, 단순 메모리 접근)
    • 하지만 동기화 문제(레이스 컨디션) 발생 가능 → 세마포어, 뮤텍스 필요
  • 예시: 생산자-소비자 문제, 대규모 데이터 교환

(2) 메시지 전달 시스템 (Message Passing)

  • 개념: 운영체제가 제공하는 커널 버퍼를 통해 프로세스들이 메시지를 송수신
  • 특징:
    • 커널을 거쳐야 해서 상대적으로 느림
    • 동기화 문제는 OS가 관리 → 구현 간단, 안전성 높음
  • 방식:
    • 직접 통신: 프로세스들이 서로의 ID를 알고 직접 메시지 교환
    • 간접 통신: 메일박스(mailbox), 포트(port) 같은 추상화된 채널 이용

3. 주요 IPC 기법

(1) 파이프 (Pipe)

  • 개념: 두 프로세스 간 단방향 통신 채널
  • 특징:
    • 한쪽은 쓰기(write), 다른 쪽은 읽기(read) 전용
    • 부모-자식 프로세스 간 자주 사용
    • 익명 파이프: 같은 계열 프로세스 간
    • 명명된 파이프(Named Pipe, FIFO): 무관한 프로세스 간도 가능

(2) 메시지 큐 (Message Queue)

  • 개념: 커널이 제공하는 큐(Queue) 자료구조를 사용
  • 특징:
    • 비동기적 메시지 전달 가능
    • 메시지 우선순위 지정 가능

(3) 소켓 (Socket)

  • 개념: 네트워크 기반 IPC 기법
  • 특징:
    • 동일 시스템 내 프로세스뿐 아니라, 다른 시스템 간 통신도 가능
    • TCP/UDP 기반으로 동작 → 클라이언트-서버 모델에 적합

(4) RPC (Remote Procedure Call)

  • 개념: 원격 프로세스의 함수를 마치 로컬 함수처럼 호출하는 기법
  • 특징:
    • 네트워크/분산 시스템에서 자주 사용
    • 호출 측은 네트워크 세부사항을 몰라도 함수 호출처럼 사용 가능
    • 내부적으로는 메시지 전달, 직렬화, 소켓 통신 등으로 구현

(5) 기타 IPC

  • 세마포어 (Semaphore): 동기화 및 상호 배제를 위한 카운터 기반 메커니즘
  • 공유 파일 (Shared File): 파일을 매개로 데이터 교환, 단 느리고 동기화 필요

4. 정리 표

방식 특징 장점 단점 활용 예

공유 메모리 메모리 영역 직접 공유 빠름 동기화 필요 생산자-소비자 버퍼
메시지 전달 커널이 메시지 송수신 관리 구현 단순, 안전 느림 분산 환경 프로세스 간 통신
파이프 단방향 스트림 간단, 부모-자식 간 통신 용이 단방향 제한 Unix 파이프(`
메시지 큐 커널의 큐 이용 비동기, 우선순위 지원 커널 자원 한정 IPC 채팅, 로깅
소켓 네트워크 기반 원격 통신 가능 구현 복잡 웹 서버-클라이언트
RPC 원격 함수 호출 추상화, 편리 내부 구현 복잡 분산 시스템, 마이크로서비스

✅ 요약:

  • IPC 모델: 공유 메모리 vs 메시지 전달
  • 주요 기법: 파이프, 메시지 큐, 소켓, RPC 등
  • 선택 기준: 데이터 크기, 속도 요구, 안정성, 프로세스 관계(같은 시스템 vs 분산 시스템)

 

스레드(Thread)의 정의

  • CPU 이용의 기본 단위
  • 프로세스 내에서 실행되는 실행 흐름 단위를 의미합니다.
  • 프로세스는 최소 1개의 스레드를 가지며, 멀티스레딩을 통해 하나의 프로세스에서 여러 스레드가 병렬로 실행될 수 있습니다.

스레드의 구성 요소

스레드마다 독립적으로 가지는 부분:

  • Thread ID : 스레드 고유 식별자
  • PC(Program Counter) : 명령어의 실행 위치
  • 레지스터 집합 : 연산에 필요한 임시 데이터 저장
  • 스택(Stack) : 함수 호출, 지역 변수 저장

스레드가 같은 프로세스 내에서 공유하는 부분:

  • 코드(Code) 영역
  • 데이터(Data) 영역
  • 운영체제 자원 (파일 핸들, 소켓 등)

스레드의 종류

  1. 사용자 스레드 (User Thread)
    • 사용자 수준 라이브러리에서 지원하는 스레드
    • 커널이 직접 인식하지 못하고, 하나의 프로세스 단위로 스케줄링됨
    • 장점: 생성/전환 속도가 빠르고, 오버헤드가 적음
    • 단점: 하나의 스레드가 커널 호출로 블록되면, 전체 프로세스가 블록될 수 있음
  2. 커널 스레드 (Kernel Thread)
    • 운영체제 커널이 직접 관리하는 스레드
    • 커널이 스케줄링하므로 다중 CPU 활용 가능
    • 단점: 생성/전환 시 시스템 콜이 필요해 비용이 크다

👉 정리하면, 스레드 = 프로세스 내 실행 흐름의 최소 단위이고,

**독립적인 실행 상태(PC, 레지스터, 스택)**는 따로 가지지만,

코드/데이터/자원은 같은 프로세스 내 스레드끼리 공유한다는 특징이 있습니다.

fork()와 스레드

  • POSIX 표준에 따르면 fork()는 호출한 스레드만 복사합니다.
  • 즉:
    • 부모 프로세스 → 여러 스레드 존재 가능
    • 자식 프로세스 → fork를 호출한 그 스레드만 존재 (다른 스레드는 복사되지 않음)
  • 이유: 모든 스레드를 그대로 복제하면 동기화 상태, 락(lock) 보유 상태 등이 복잡해져서 일관성을 깨뜨릴 수 있기 때문이에요.

👉 따라서, fork() 후에는 자식 프로세스는 단일 스레드 상태로 시작하고, 필요하면 exec()를 호출해 새 프로그램으로 덮어씌우는 경우가 많습니다.


🔹 exec()

  • exec 계열 함수(execl, execv, execve 등)는 현재 프로세스 전체를 새로운 프로그램으로 대체합니다.
  • 프로세스 메모리 공간, 코드, 데이터, 스택이 모두 교체되고, 기존 스레드는 모두 사라집니다.
  • 즉:
    • 호출한 프로세스의 PID는 유지됨
    • 실행 이미지는 완전히 새 프로그램으로 바뀜
    • 남는 스레드 없음 → 새 프로그램은 항상 단일 스레드로 시작

✅ 정리하면:

  • fork() → 호출한 스레드만 복사 (자식은 단일 스레드 상태).
  • exec() → 전체 프로세스를 대체 (모든 스레드 사라지고 새 프로그램 시작).

🔹 스레드 풀(Thread Pool)

✅ 개념

  • 프로그램 시작 시 일정 개수의 스레드를 미리 생성해두고, 이 스레드들을 작업(Task) 큐에 있는 일을 처리하는 데 재사용하는 방식.
  • 즉, 매번 새로운 스레드를 만들고 없애는 대신, **재활용(Recycling)**하는 구조.

✅ 동작 방식

  1. 스레드 풀 초기화 → 정해진 개수의 워커 스레드(worker thread) 생성.
  2. 클라이언트/사용자가 작업을 요청 → 작업이 **작업 큐(task queue)**에 들어감.
  3. 대기 중이던 워커 스레드가 큐에서 작업을 꺼내 실행.
  4. 작업 완료 후 → 스레드는 종료되지 않고 다시 큐를 감시하며 다음 작업 대기.

✅ 장점

  • 생성/제거 오버헤드 감소: 스레드를 매번 만들지 않고 재사용하므로 성능 향상.
  • 동시성 제어 용이: 풀 크기를 제한하면 동시에 실행되는 스레드 수를 조절 가능 → CPU 과부하 방지.
  • 응답 시간 단축: 요청이 들어올 때마다 바로 실행할 스레드가 준비되어 있음.

❌ 단점

  • 풀 크기 설정 어려움: 너무 작으면 병목, 너무 크면 문맥 전환 오버헤드 발생.
  • 장시간 블로킹 작업 문제: 워커 스레드가 오래 점유되면 다른 작업이 밀릴 수 있음.
  • 복잡성 증가: 큐 관리, 예외 처리, 동기화 관리가 필요.

🔹 동기(Synchronous) vs 비동기(Asynchronous)

  • 동기(Sync)
    • 요청한 작업이 끝날 때까지 호출한 쪽이 결과를 기다림.
    • 제어 흐름이 작업 완료 시점과 맞춰져 있음.
    • 예: read() 호출 → 데이터 다 읽을 때까지 반환하지 않음.
  • 비동기(Async)
    • 요청한 작업을 백그라운드에서 수행하고, 호출한 쪽은 즉시 반환받음.
    • 결과는 나중에 이벤트, 콜백, Future/Promise 등을 통해 알림.
    • 예: aio_read() → 바로 return, 읽기 완료되면 알림.

👉 즉, “동기는 결과 반환을 기다리고, 비동기는 기다리지 않는다”는 표현은 정확합니다


🔹 블로킹(Blocking) vs 논블로킹(Non-blocking)

  • 블로킹(Blocking)
    • 호출한 함수가 즉시 결과를 줄 수 없으면 → 호출한 스레드를 멈추고 대기.
    • 제어권을 커널/라이브러리 쪽에 넘겨주고, 작업이 끝날 때까지 안 돌려줌.
    • 예: read(fd, buf, size)에서 읽을 데이터가 없으면, 데이터가 올 때까지 멈춤.
  • 논블로킹(Non-blocking)
    • 호출한 함수가 즉시 결과를 줄 수 없으면 에러/특정 코드(EAGAIN 등)를 반환.
    • 즉, 제어권을 바로 돌려줌.
    • 예: read(fd, buf, size) 호출 시 읽을 게 없으면 1 즉시 반환.

👉 따라서 “블로킹은 제어권을 넘기고, 논블로킹은 제어권을 넘기지 않는다”는 표현은 살짝 부정확해요.

정확히는:

  • 블로킹 → 제어권을 넘겨주고 작업 완료까지 반환 안 함.
  • 논블로킹 → 제어권을 넘겨주긴 하지만, 결과 없으면 즉시 반환해서 호출자가 다시 사용할 수 있음.

🔹 한눈에 정리 (표)

구분 동기 비동기

블로킹 작업 끝날 때까지 기다림 (ex. read()) 콜백/알림을 쓰지만, 호출 자체는 블로킹됨 (드묾)
논블로킹 즉시 반환, 호출자가 반복 확인해야 함 (ex. read() + 반복) 즉시 반환 + 완료되면 알림/콜백 (ex. 이벤트 기반 I/O)

✅ 정리하면:

  • 동기/비동기 → “작업 완료 통보 방식”
  • 블로킹/논블로킹 → “호출 시 제어권 반환 여부”

 

CPU 스케줄링

 

CPU를 프로세스 들 간에 교환함

일반적으로 프로세스 스케줄링을 뜻함

CPU 스케줄러 (CPU Scheduler)

CPU가 유휴 상태가 될 때마다 **운영체제(OS)**는 **준비 완료 큐(Ready Queue)**에 있는 프로세스들 중 하나를 골라 실행합니다.

이 과정은 **단기 스케줄러(Short-term Scheduler)**가 담당합니다.

  • 역할: 메모리 내에서 실행 준비가 된 프로세스 중 하나를 선택 → CPU에 할당
  • 목표: CPU 이용률 극대화, 처리량 증가, 대기 시간·응답 시간 최소화, 공정성 보장

1. 스케줄링 종류

① 비선점 스케줄링 (Non-preemptive Scheduling)

  • 한 프로세스가 CPU를 할당받으면 자신이 종료되거나 대기 상태로 전환될 때까지 CPU를 계속 사용
  • 다른 프로세스는 기다려야 함
  • 장점: 컨텍스트 스위칭 오버헤드가 적음
  • 단점: 응답 시간이 길어질 수 있음
  • 예시 알고리즘
    • FCFS (First Come First Serve)
    • SJF (Shortest Job First)
    • HRN (Highest Response Ratio Next)

② 선점 스케줄링 (Preemptive Scheduling)

  • 실행 중인 프로세스가 있더라도 우선순위가 더 높은 프로세스가 도착하면 CPU를 빼앗아 올 수 있음
  • 장점: 응답 시간이 짧아져 대화형 시스템에 적합
  • 단점: 잦은 컨텍스트 스위칭으로 오버헤드 증가, 교착 상태(deadlock)나 기아(starvation) 발생 가능
  • 에이징(Aging) 기법으로 낮은 우선순위 프로세스의 기아 문제를 완화
  • 예시 알고리즘
    • SRTF (Shortest Remaining Time First)
    • Priority Scheduling
    • Round Robin (RR)
    • Multilevel Queue / Feedback Queue

2. 디스패처 (Dispatcher)

  • 정의: 단기 스케줄러가 선택한 프로세스에게 실제로 CPU 제어권을 넘겨주는 모듈
  • 주요 역할
    • 컨텍스트 스위칭 (context switching)
    • 사용자 모드 전환
    • 프로그램의 올바른 위치(PC, 레지스터)에서 실행 재개
  • 디스패처 지연 (Dispatcher Latency)
    • 하나의 프로세스에서 다른 프로세스로 CPU 제어가 넘어가는 데 걸리는 시간
    • → 너무 길면 시스템 성능 저하

📌 정리하면,

  • 단기 스케줄러: 어떤 프로세스가 CPU를 쓸지 선택
  • 디스패처: 실제로 CPU를 넘겨주는 실행자
  • 비선점/선점 여부에 따라 응답성과 공정성이 달라짐

 

임계구역 문제

임계구역 문제 (Critical Section Problem)

여러 프로세스가 공유 자원(메모리, 파일, I/O 장치 등)에 접근할 때 **경쟁 조건(Race Condition)**을 피하기 위해 필요한 규칙을 정의한 것. 이를 위해 운영체제는 임계구역에 대한 접근을 제어하는 프로토콜을 설계해야 함.

1. 요구 조건 (3가지 조건)

  1. 상호 배제 (Mutual Exclusion)
    • 한 번에 하나의 프로세스만 임계구역에 진입할 수 있어야 함.
    • 다른 프로세스가 이미 임계구역에 있으면, 나머지는 대기해야 함.
  2. 진행 (Progress)
    • 임계구역에 들어가려는 프로세스가 없을 경우, 들어갈 프로세스를 결정하는 데 불필요한 지연이 없어야 함.
    • 즉, CPU가 놀고 있는데도 임계구역 진입을 막으면 안 됨.
  3. 한정된 대기 (Bounded Waiting)
    • 특정 프로세스가 임계구역 진입을 무한정 기다리게 두어서는 안 됨.
    • 언젠가는 반드시 임계구역에 들어갈 수 있어야 한다는 공정성 보장 조건.

커널의 선점 여부

운영체제의 커널이 프로세스를 언제까지 실행시키는지와 관련 있음.

1. 비선점형 커널 (Non-preemptive Kernel)

  • 커널 모드에 들어간 프로세스는 스스로 CPU를 양보하거나 작업이 끝날 때까지 계속 실행.
  • 장점: 동기화가 상대적으로 단순 → 임계구역 충돌 발생 확률 낮음.
  • 단점: 한 프로세스가 오래 점유하면 다른 프로세스 대기 시간이 길어짐 → 시스템 반응성 저하.

2. 선점형 커널 (Preemptive Kernel)

  • 커널 모드에서 실행 중이더라도 운영체제가 강제로 CPU를 빼앗아 다른 프로세스 실행 가능.
  • 장점: 시스템 반응성 ↑ (특히 실시간 시스템에 적합).
  • 단점: 임계구역에서 선점되면 동기화 문제 발생 → 세마포어, 뮤텍스, 모니터 같은 동기화 도구 필요.

✅ 요약

  • 임계구역 문제 → 상호배제, 진행, 한정된 대기 조건 충족 필요.
  • 비선점형 커널은 단순하지만 비효율적, 선점형 커널은 효율적이지만 동기화 기법 필요.

피터슨 알고리즘

피터슨 알고리즘 (Peterson’s Algorithm)

  • 정의: 두 개의 프로세스가 하나의 공유 자원을 안전하게 사용할 수 있도록 보장하는 소프트웨어 기반 임계구역 해결 알고리즘.
  • 아이디어: "상호 배제"를 위해 플래그 변수 + turn 변수를 이용해 락(Locking) 개념을 구현.

1. 기본 구조

  • flag[2]: 프로세스가 임계구역에 들어가고 싶다는 의사를 표시 (true/false)
  • turn: 두 프로세스 중 누구 차례인지를 알려주는 변수
// 프로세스 i의 코드 (i = 0 or 1)
do {
    flag[i] = true;              // 임계구역 진입 의사 표시
    turn = j;                    // 상대방 차례로 설정
    while (flag[j] && turn == j); // 상대방이 원하고 차례이면 대기

    // ---- 임계구역 시작 ----
    critical_section();
    // ---- 임계구역 끝 ----

    flag[i] = false;             // 임계구역 나옴
    remainder_section();
} while (true);


2. 특징 (3대 조건 충족 여부)

  1. 상호 배제 (Mutual Exclusion)
    • 두 프로세스가 동시에 임계구역에 진입할 수 없음.
    • flag와 turn 조합으로 보장.
  2. 진행 (Progress)
    • 임계구역을 원하지 않는 프로세스는 다른 프로세스의 진입을 방해하지 않음.
  3. 한정된 대기 (Bounded Waiting)
    • 한 프로세스가 무한정 기다리지 않도록 보장 (turn 변수가 번갈아 기회를 줌).

3. 장단점

  • 장점
    • 순수 소프트웨어적 방법 (하드웨어 지원 필요 없음).
    • 임계구역 문제의 3대 조건을 모두 만족.
  • 단점
    • 두 프로세스 환경에서만 동작 (N개 프로세스는 불가능).
    • 현대의 멀티코어 환경에서는 메모리 재정렬/캐시 동기화 문제 때문에 실제로는 쓰이지 않음.
    • 대신 하드웨어 기반 Test-and-Set, Compare-and-Swap 같은 명령어나 세마포어, 뮤텍스, 모니터를 사용.

4. 락킹과의 관계

  • Peterson 알고리즘은 락(Lock) 개념을 소프트웨어적으로 구현한 초기 방식.
  • 단일 CPU 환경에서는 "인터럽트 금지" 방식으로도 해결 가능했지만, 멀티코어·멀티프로세서 환경에서는 하드웨어 락 지원 없이는 Peterson 알고리즘이 깨질 수 있음.

👉 정리: Peterson 알고리즘은 교과서적 중요성이 크고, 실제 시스템에서는 하드웨어 명령어나 동기화 도구가 더 많이 사용됨.

뮤텍스 락 (Mutex Lock)

  • Mutual Exclusion의 줄임말.
  • 임계구역(critical section)에 진입하기 전에 **락(lock)**을 획득해야 하고, 임계구역에서 나오면서 반드시 **락을 해제(unlock)**해야 함.
  • 한 시점에는 오직 하나의 프로세스/스레드만 락을 보유할 수 있음 → 상호 배제 보장.

1. 기본 원리

// Pseudo code
acquire(lock);     // 임계구역 들어가기 전에 락 획득
critical_section();
release(lock);     // 임계구역 빠져나올 때 락 반환

  • acquire(): 락을 얻을 수 있을 때까지 기다림.
  • release(): 락을 다른 프로세스가 사용할 수 있도록 반환.

2. 장점

  • 구현이 단순하고 직관적.
  • 선점형 커널 환경에서도 안전하게 임계구역 보호 가능.
  • 현대 운영체제에서 스레드 동기화 기본 도구로 널리 사용됨.

3. 단점

  1. 바쁜 대기 (Busy Waiting, Spin Lock)
    • 프로세스가 락을 얻을 때까지 계속 루프를 돌며 기다림 → CPU 낭비.
    • 예:
    • while (lock == 1); // 다른 스레드가 락 반환할 때까지 계속 반복
  2. 데드락(Deadlock) 가능
    • 락을 해제하지 못하거나, 여러 락을 교착 상태로 요청할 경우 발생.
  3. 우선순위 역전(Priority Inversion)
    • 낮은 우선순위 프로세스가 락을 보유하면, 높은 우선순위 프로세스도 기다려야 함.

4. 개선 방법

  • 세마포어(Semaphore): 대기 상태를 큐에 넣고 블록(block) → 바쁜 대기 해결.
  • 모니터(Monitor): 고수준 언어에서 동기화 지원.
  • 혼합 기법: 짧은 시간은 스핀 락, 오래 걸리면 블록 (하이브리드 락).

✅ 요약

  • 뮤텍스 락은 상호 배제를 보장하는 가장 단순한 방법.
  • 하지만 기본 구현은 바쁜 대기(Spin Lock) 문제를 가진다.
  • 실제 시스템에서는 세마포어나 모니터 등과 함께 개선된 형태로 사용된다.

세마포어 (Semaphore)

  • 1965년 Dijkstra가 제안한 동기화 기법.
  • 공유 자원에 대한 접근을 제어하기 위해 **정수 변수 S와 두 개의 원자적 연산(wait, signal)**을 사용.
  • 커널이 제공하는 원자적 연산이기 때문에 동시 실행 환경에서도 안전하게 동작.

1. 두 가지 연산

  1. wait (P 연산)
    • 자원을 얻기 전 검사
    • 사용 가능 자원이 없으면 대기
  2. wait(S) { while (S <= 0); // 바쁜 대기 (Spin) or 블록 S--; }
  3. signal (V 연산)
    • 자원 사용이 끝난 후 반환
  4. signal(S) { S++; }

2. 세마포어의 종류

  1. 이진 세마포어 (Binary Semaphore)
    • 값이 0 또는 1만 가짐.
    • 사실상 뮤텍스 락과 동일하게 동작.
    • 임계구역 보호에 사용.
  2. 계수 세마포어 (Counting Semaphore)
    • 값이 0 이상 정수.
    • 동시에 여러 개의 프로세스가 공유 자원에 접근할 수 있도록 허용.
    • 예: DB 연결 풀, 프린터 3대 → 초기값 S=3.

3. 특징

장점

  • 뮤텍스보다 일반적: 여러 자원 동시 관리 가능.
  • 바쁜 대기 문제 해결 가능: 대기 중인 프로세스를 큐에 넣어 블록시키고, signal 시 깨움.

⚠️ 단점

  • 프로그래밍 실수 위험 (wait/signal 불일치 → 데드락, 기아 문제).
  • 관리가 어렵기 때문에 고수준 언어에서는 **모니터(Monitor)**가 더 선호됨.

4. Mutex vs Semaphore 비교

구분 뮤텍스(Mutex) 세마포어(Semaphore)

자원 수 1개만 보호 N개 자원까지 보호 가능
0/1 (binary) 0 이상 정수
소유권 스레드가 소유 (owner만 unlock 가능) 소유 개념 없음
사용 용도 임계구역 보호 자원 개수 제어, 프로세스 동기화
구현 난이도 단순 상대적으로 복잡

✅ 요약

  • 세마포어 = 정수 변수 + wait/signal 연산
  • 이진 세마포어 = 뮤텍스
  • 계수 세마포어 = 여러 자원 관리 가능
  • 하지만 프로그래밍 복잡성 때문에 실무에서는 주로 뮤텍스 + 조건변수, 모니터를 사용

1. 모니터(Monitor)란?

  • 고수준 언어에서 제공하는 동기화 도구
  • 세마포어처럼 직접 wait/signal을 다루는 대신, 언어 차원에서 임계구역 진입/대기/신호를 관리해줌.
  • 즉, 프로그래머가 동기화 로직을 일일이 짜는 대신, 모니터가 자동으로 상호배제를 보장해 줌.

➡️ 세마포어의 단점(코드 복잡성, wait/signal 불일치 → 교착상태 가능)을 해결하기 위한 추상화 기법.


2. 모니터의 구성 요소

  1. 공유 변수 (Shared Variables)
    • 모니터 내부에서만 접근 가능한 자원(데이터 구조).
  2. 프로시저 (Procedures)
    • 공유 변수를 접근할 수 있는 루틴.
    • 임계구역은 이 루틴 안에서만 존재하며, 자동으로 상호배제 보장.
  3. 조건 변수 (Condition Variables)
    • 모니터 안에서 프로세스 동기화를 위해 사용.
    • wait() : 현재 프로세스를 조건 대기 큐에 넣고, 다른 프로세스에게 제어권 넘김.
    • signal() : 대기 중인 프로세스를 깨움.

3. 모니터 동작 방식

  • 한 번에 하나의 프로세스만 모니터 내부 실행 가능.
  • 다른 프로세스가 들어오면 자동으로 블록됨 (상호배제 보장).
  • 조건 변수로 대기/신호를 제어 → 세마포어 wait/signal과 유사하지만 자동 관리됨.

4. 예시 (생산자-소비자 문제)

monitor ProducerConsumer {
    int buffer[N];
    int count = 0;
    condition notFull, notEmpty;

    procedure insert(item) {
        if (count == N) wait(notFull);  // 버퍼가 꽉 찼으면 대기
        buffer[count++] = item;
        signal(notEmpty);               // 소비자에게 알림
    }

    procedure remove() {
        if (count == 0) wait(notEmpty); // 버퍼가 비었으면 대기
        item = buffer[--count];
        signal(notFull);                // 생산자에게 알림
        return item;
    }
}

  • 생산자는 insert() 호출 → 버퍼 꽉 차면 wait(notFull).
  • 소비자는 remove() 호출 → 버퍼 비면 wait(notEmpty).
  • 모니터는 상호배제 + 동기화를 자동 관리.

5. 장단점

장점

  • 상호배제 자동 보장 → 프로그래머가 실수로 놓칠 위험 감소.
  • 코드 가독성 높고, 동기화 오류 줄어듦.
  • 고급 언어(Java, C#, Python 등)에서 널리 지원 (synchronized, lock 구문 등).

⚠️ 단점

  • 구현이 복잡해 하드웨어/저수준 언어(C)에서는 직접 지원 어렵다.
  • 잘못된 조건 변수 사용 시 기아 가능성.

6. 현대 운영체제와 모니터

  • Java → synchronized 블록, wait() / notify()
  • C# → lock, Monitor.Wait() / Monitor.Pulse()
  • Python → threading.Condition

즉, 세마포어는 OS 수준의 원시적 도구라면,

모니터는 언어/런타임 수준의 고수준 동기화 도구라 할 수 있음.


✅ 요약

  • 모니터는 세마포어보다 추상화된 동기화 도구.
  • 프로세스/스레드가 동시에 모니터 안에 들어올 수 없도록 상호배제를 자동 보장.
  • 조건 변수(wait, signal)를 통해 세밀한 동기화 제어 가능.

 

교착상태 & 기아

1. 교착상태 (Deadlock)

  • 정의: 프로세스들이 서로가 가진 자원을 기다리며 무한 대기 상태에 빠진 것.
  • 예: P1은 프린터를 가지고 플로터를 기다리고, P2는 플로터를 가지고 프린터를 기다리는 경우.

발생 조건 (Coffman의 4가지 조건 – 모두 만족해야 발생)

  1. 상호 배제 (Mutual Exclusion)
  2. 자원은 한 번에 한 프로세스만 사용 가능.
  3. 점유 대기 (Hold and Wait)
  4. 최소 하나의 자원을 점유한 채로 다른 자원을 기다림.
  5. 비선점 (No Preemption)
  6. 할당된 자원은 강제로 빼앗을 수 없음.
  7. 순환 대기 (Circular Wait)
  8. 프로세스들이 원형으로 서로가 가진 자원을 기다림.

2. 기아 (Starvation)

  • 정의: 특정 프로세스가 우선순위 문제나 자원 할당 정책 때문에 무한히 자원을 얻지 못하고 기다리는 상태.
  • 예: 우선순위 스케줄링에서 낮은 우선순위 프로세스가 계속 밀려 실행되지 못하는 경우.

원인

  • 우선순위 기반 스케줄링
  • 자원 할당 시 특정 프로세스에 불리한 정책
  • 무한 대기 큐 구조

3. 우선순위 역전 (Priority Inversion)

  • 정의: 낮은 우선순위 프로세스가 자원을 가지고 있어서, 높은 우선순위 프로세스가 그 자원을 기다리며 실행되지 못하는 상황.
  • 중간 우선순위 프로세스가 계속 실행되면 높은 우선순위 프로세스는 더 오래 기다리게 됨 → 실질적 기아 발생.

해결 방법

  • Priority Inheritance (우선순위 상속):
  • 낮은 우선순위 프로세스가 자원을 가지고 있으면 임시로 높은 우선순위를 부여해 빠르게 자원 반환하도록 함.
  • Priority Ceiling (우선순위 천장):
  • 공유 자원에 대해 최대 우선순위를 미리 지정해, 해당 자원에 접근 시 우선순위를 높여줌.

4. 교착상태 vs 기아 비교

구분 교착상태 (Deadlock) 기아 (Starvation)

정의 프로세스들이 서로 자원을 기다리며 영원히 대기 특정 프로세스가 무한히 자원을 못 얻는 상태
원인 자원 할당의 원형 대기 우선순위 정책, 불공정 스케줄링
발생 조건 Coffman 4조건 필요 특정 조건 없음
해결 예방, 회피, 탐지 및 회복 Aging(우선순위 점진 상향), 공정 스케줄링

✅ 요약

  • 교착상태: 여러 프로세스가 서로 자원을 기다리며 꼼짝 못하는 상태 (시스템 전체 멈춤).
  • 기아: 특정 프로세스가 무한히 자원을 못 얻는 상태 (불공정성).
  • 우선순위 역전은 기아의 한 사례 → 우선순위 상속/천장 기법으로 해결 가능.

교착상태 해결 방법

교착상태를 다루는 방법은 크게 네 가지로 나눌 수 있습니다:


1. 예방 (Deadlock Prevention)

  • Coffman의 4가지 필요 조건 중 하나 이상을 아예 성립하지 않도록 설계하는 방식.

방법

  1. 상호 배제(Mutual Exclusion) 부정
    • 자원을 여러 프로세스가 동시에 사용할 수 있게 설계 (현실적으로 모든 자원에 불가능).
  2. 점유 대기(Hold & Wait) 부정
    • 프로세스가 실행 전에 필요한 모든 자원을 한 번에 할당.
    • 단점: 자원 활용률↓, 기아 발생 가능.
  3. 비선점(No Preemption) 부정
    • 자원을 빼앗을 수 있게 함 (ex: CPU 스케줄링 선점형, 메모리 페이지 스왑).
  4. 순환 대기(Circular Wait) 부정
    • 자원에 번호를 붙여, 오름차순으로만 할당.

➡️ 장점: 교착상태 자체를 원천적으로 막음.

➡️ 단점: 자원 낭비, 활용률 저하.


2. 회피 (Deadlock Avoidance)

  • 교착상태가 발생하지 않도록 자원 할당을 신중히 결정하는 방식.
  • 대표적 방법: 은행가 알고리즘 (Banker’s Algorithm)
    • 자원 요청 시, 현재 상태가 **안전 상태(Safe State)**인지 검사 후 허용.
    • 안전하지 않으면 요청을 거절.

➡️ 장점: 교착상태 자체를 피할 수 있음.

➡️ 단점: 프로세스의 최대 자원 요구량을 미리 알아야 함 → 비현실적.


3. 탐지 후 회복 (Deadlock Detection & Recovery)

  • 교착상태 발생을 허용하되, 탐지 알고리즘으로 발견하고 이후 회복.

탐지 방법

  • 자원 할당 그래프(Resource Allocation Graph) 활용
    • 순환(Cycle)이 있으면 교착상태 가능.

회복 방법

  1. 프로세스 종료
    • 교착상태에 연루된 프로세스들을 강제로 종료.
    • 한 번에 모두 종료 vs 하나씩 종료.
  2. 자원 선점(Preemption)
    • 일부 프로세스에서 자원을 빼앗아 다른 프로세스에 할당.
    • 단점: 프로세스 상태 rollback 필요 → 오버헤드 발생.

4. 무시 (Deadlock Ignorance)

  • 교착상태를 해결하는 비용이 너무 크기 때문에, 실제로는 무시하는 방법.
  • 대부분의 범용 OS (Windows, Linux, macOS)는 이 방법 사용.
  • 교착상태 발생 빈도가 낮고, 발생 시 시스템을 재부팅하면 됨.

➡️ 장점: 구현 단순, 오버헤드 없음.

➡️ 단점: 일부 프로세스가 멈출 수 있음.


✅ 요약

방법 특징 장점 단점

예방 (Prevention) 4조건 중 하나 제거 교착상태 절대 발생 X 자원 낭비, 비효율
회피 (Avoidance) 안전 상태 유지 교착상태 피할 수 있음 최대 자원 요구량 필요
탐지 & 회복 (Detection & Recovery) 교착상태 허용 후 탐지·복구 자원 활용률 ↑ 탐지·복구 비용 큼
무시 (Ignore) 그냥 무시 단순, 효율 ↑ 교착상태 시 시스템 멈춤

 

 

메모리 관리 전략

 

CPU는 PC(program counter)가 지시하는데로 메모리에서 다음 수행할 명령어를 가져옴

주 메모리 ↔ 프로세서 자체에 내장한 레지스터는 CPU의 유일한 범용 저장장치

주 메모리 접근시 속도 차이로 cpu클록 틱 사이클이 소요되고, 지연(stall) 현상이 발생함

논리, 물리 주소

1. CPU와 메모리 접근

  • CPU는 **프로그램 카운터(PC, Program Counter)**가 가리키는 메모리 주소에서 명령어를 가져와 실행.
  • CPU 내부에는 **레지스터(Register)**가 있어서 연산에 직접 사용되는 데이터를 저장.
  • *주 메모리(Main Memory, RAM)**는 CPU가 데이터를 읽고 쓰는 기본 저장 장치지만, **CPU 클록 대비 속도가 느려 지연(stall)**이 발생.
    • 이를 줄이기 위해 **캐시 메모리(Cache)**가 등장 (CPU ↔ 캐시 ↔ 메모리 구조).

2. 논리 주소와 물리 주소

  • 논리 주소(Logical Address, 가상주소)
    • CPU가 생성하는 주소 (프로그램 관점).
    • 각 프로세스는 독립적인 주소 공간을 가진다고 "착각"할 수 있음.
  • 물리 주소(Physical Address)
    • 실제 메모리 하드웨어(RAM)가 갖는 주소.
  • 주소 변환(Address Translation)
    • *MMU (Memory Management Unit)**가 논리 주소 → 물리 주소 변환을 담당.
    • 보통 **재배치 레지스터(Relocation Register)**를 사용해서 시작 위치를 보정.

➡️ 이를 통해 다중 프로세스 환경에서도 서로 간섭하지 않고 메모리 사용 가능.


3. 동적 적재 (Dynamic Loading)

  • 프로세스 전체를 메모리에 올리지 않고, 필요한 부분만 메모리에 적재.
  • 장점: 메모리 사용 효율 ↑, 다중 프로그래밍에 유리.
  • 예: 라이브러리를 호출할 때 실제 필요한 함수만 메모리에 로드.

4. 메모리 할당 기법 (연속 메모리 할당)

프로세스들을 메모리에 배치할 때, 빈 공간(free hole)을 어떻게 선택할지 결정하는 방식.

  1. 최초 적합(First Fit)
    • 처음 발견한 충분히 큰 공간에 배치.
    • 속도 빠름, 하지만 단편화(fragmentation) 발생 가능.
  2. 최적 적합(Best Fit)
    • 크기가 가장 작은, 딱 맞는 공간에 배치.
    • 메모리 낭비 최소화, 그러나 작은 조각(외부 단편화) 많이 생김.
  3. 최악 적합(Worst Fit)
    • 가장 큰 공간에 배치.
    • 큰 공간을 나눠 사용 → 큰 프로세스를 위한 공간 확보 가능.
    • 하지만 실제 효율은 떨어짐.

✅ 요약

  • CPU ↔ 메모리 속도 차이를 줄이기 위해 캐시가 필요.
  • 논리 주소는 CPU가 보는 주소, 물리 주소는 실제 메모리 주소.
  • MMU가 주소 변환 수행.
  • 동적 적재로 메모리 효율성을 높임.
  • 메모리 배치 기법: 최초 적합, 최적 적합, 최악 적합 → 각각 속도/효율/낭비 측면에서 장단점 다름.

*** 동적 할당 → 외부 단편화 발생

1. 단편화(Fragmentation)

메모리 할당 과정에서 생기는 사용하지 못하는 빈 공간 문제.

(1) 외부 단편화 (External Fragmentation)

  • 여러 번의 메모리 할당/해제로 인해 자잘한 빈 공간이 여기저기 흩어져 전체적으로는 충분한 메모리가 있어도 큰 프로세스를 넣을 수 없는 상황.
  • 예: 10KB 프로세스 필요 → 빈 공간이 2KB+3KB+5KB로 나뉘어 있으면 수용 불가.
  • 해결 방법:
    • 압축(Compaction): 메모리 내용을 옮겨서 빈 공간을 하나로 모음.

(2) 내부 단편화 (Internal Fragmentation)

  • 할당된 블록이 실제 요구보다 큰 경우 발생 → 블록 내에 낭비된 공간 존재.
  • 예: 12KB 요청 → 16KB 단위 블록 할당 → 4KB 낭비.

2. 세그멘테이션 (Segmentation)

  • *프로그래머가 논리적으로 프로그램을 나눈 단위(세그먼트)**를 메모리에 배치하는 기법.
  • 세그먼트 = 코드, 데이터, 스택 등 가변 크기 블록.
  • CPU가 생성하는 주소 = (세그먼트 번호, 오프셋)
  • *세그먼트 테이블(Segment Table)**을 통해 물리 주소 변환.

✅ 장점:

  • 프로그래머 관점 그대로 메모리 관리 가능 (논리적 단위 유지).
  • 외부 단편화 발생하지만, 내부 단편화는 적음.

3. 페이징 (Paging)

  • 메모리를 고정 크기 블록으로 나누는 기법.
  • 프레임(Frame): 물리 메모리를 나눈 블록.
  • 페이지(Page): 프로세스의 논리 주소 공간을 나눈 블록.
  • 크기 동일 (예: 4KB).

➡️ CPU가 생성하는 주소 = (페이지 번호, 페이지 오프셋)

➡️ 페이지 테이블(Page Table): 페이지 번호 → 프레임 번호 변환.

✅ 장점:

  • 외부 단편화 없음 (모두 같은 크기).
  • 내부 단편화만 발생 (마지막 페이지 일부 낭비).

4. TLB (Translation Lookaside Buffer)

  • 페이지 테이블 접근은 메모리 참조이므로 느림 → 매번 하면 2번 메모리 접근(페이지 테이블 + 실제 데이터) 필요.
  • 이를 줄이기 위해 TLB라는 고속 캐시 사용.
  • 최근 변환된 페이지 번호 ↔ 프레임 번호를 저장해 주소 변환 속도 향상.

✅ 요약

  • 단편화
    • 외부 단편화: 작은 조각 흩어짐 → 압축 or 페이징/세그멘테이션으로 해결.
    • 내부 단편화: 블록 단위 때문에 남는 공간 발생.
  • 세그멘테이션: 논리적 단위(코드, 데이터, 스택)를 가변 크기로 관리. → 프로그래머 친화적, 외부 단편화 존재.
  • 페이징: 고정 크기 블록(Frame/Page)으로 관리. → 외부 단편화 없음, 내부 단편화 존재.
    • 페이지 테이블 필요 → 성능 저하 → TLB로 보완.

 

. 가상 메모리(Virtual Memory)란?

  • 프로세스 전체가 물리 메모리에 적재되지 않아도 실행 가능하게 하는 기법.
  • 사용자 입장에서는 매우 큰 “연속적인 메모리 공간”을 쓰는 것처럼 보이지만, 실제로는 물리 메모리(RAM)와 보조기억장치(디스크, SSD 등)를 조합해서 구현.
  • *논리 주소(가상 주소)**와 물리 주소를 분리하여 관리.

2. 필요성

  1. 메모리 효율성 향상
    • 전체 프로그램을 메모리에 올릴 필요 없이 필요한 부분만 적재 → 더 많은 프로세스를 동시에 실행 가능 (멀티프로그래밍).
  2. 보호(Protection)
    • 프로세스마다 독립적인 주소 공간 제공 → 서로 침범 불가.
  3. 유연성
    • 실제 메모리보다 큰 프로그램도 실행 가능.

1. 요구 페이징 (Demand Paging)

  • 정의: 프로세스 전체를 메모리에 적재하지 않고, 실제로 필요할 때 해당 페이지를 메모리에 적재하는 기법.
  • 프로그램 실행 시 처음에는 필요한 최소한의 페이지만 로드 → 나머지는 실행 도중 필요할 때 디스크에서 불러옴.

(1) 참조의 지역성(Locality of Reference)

  • 시간 지역성(Temporal Locality): 최근 접근한 데이터는 곧 다시 접근될 가능성 ↑
  • 공간 지역성(Spatial Locality): 접근한 주소 근처의 데이터가 곧 참조될 가능성 ↑
  • 요구 페이징은 이 성질을 활용 → 성능이 실제로는 꽤 좋음.

(2) 페이지 부재(Page Fault)

  • CPU가 요청한 페이지가 메모리에 없을 때 발생.
  • 처리 과정:
    1. CPU → 페이지 없음 감지 (트랩 발생).
    2. OS → 디스크에서 해당 페이지 적재.
    3. 페이지 테이블 갱신 후 재실행.

(3) 유효 접근 시간 (Effective Access Time, EAT)

  • 실제 메모리 접근 시간은 **페이지 부재율(p)**에 비례.

EAT=(1−p)×메모리 접근 시간+p×페이지 폴트 처리 시간EAT = (1 - p) \times \text{메모리 접근 시간} + p \times \text{페이지 폴트 처리 시간}

EAT=(1−p)×메모리 접근 시간+p×페이지 폴트 처리 시간

  • 페이지 폴트 처리 시간은 디스크 I/O가 포함되므로 매우 크다.
  • 따라서 페이지 부재율은 극히 낮아야 성능 유지 가능.

2. 쓰기 시 복사 (Copy-on-Write, COW)

  • 정의: 프로세스가 fork()나 exec()로 복제될 때, 모든 페이지를 처음부터 복사하지 않고 → 부모와 자식이 같은 물리 페이지를 공유하다가 실제로 쓰기(write) 연산이 발생하는 순간 복사하는 기법.

(1) 동작 원리

  1. fork() 시 자식 프로세스는 부모의 페이지를 그대로 참조. (읽기 전용)
  2. 어느 한쪽이 해당 페이지를 쓰기(write) 시도 → 페이지 부재 발생.
  3. OS가 그 시점에만 페이지를 새로 복사해서 분리.

(2) 장점

  • 불필요한 페이지 복사를 방지 → 메모리 절약.
  • fork() 후 exec()가 곧바로 이어지는 경우(자식이 새로운 프로그램 실행) → 부모 메모리 복사는 거의 필요 없음.

✅ 요약

  • 요구 페이징(Demand Paging)
    • 필요한 페이지만 적재 → 메모리 효율 ↑
    • 참조의 지역성 때문에 실제 성능이 만족스러움
    • 하지만 페이지 부재율이 높아지면 성능 저하 (스래싱 위험)
  • 쓰기 시 복사(Copy-on-Write, COW)
    • 부모-자식이 페이지를 공유하다가 쓰기 시점에만 복사
    • fork() + exec() 최적화에 매우 효과적

1. 페이지 교체(Page Replacement)란?

  • 가상 메모리 시스템에서, 새로운 페이지를 메모리에 불러와야 하는데 빈 프레임이 없을 때 → 기존에 있던 페이지 중 하나를 교체하는 과정.
  • 어떤 페이지를 교체하느냐에 따라 **페이지 부재율(Page Fault Rate)**이 크게 달라짐.
  • 목표: 페이지 부재율을 최소화하는 알고리즘 선택.

2. 프레임 할당 (Frame Allocation)

  • 각 프로세스에 얼마나 많은 프레임을 줄 것인지 결정.
  • 너무 적으면 → 페이지 폴트 잦음.
  • 너무 많으면 → 다른 프로세스가 부족해짐.

3. 주요 페이지 교체 알고리즘

(1) 최적 교체 (Optimal Replacement, OPT)

  • 앞으로 가장 오랫동안 사용하지 않을 페이지를 교체.
  • 이론적으로 가장 좋은 성능 → 페이지 부재율 최소.
  • 하지만 미래 참조를 알 수 없으므로 실제 구현 불가, 비교 기준으로 사용.

(2) FIFO (First-In First-Out)

  • 메모리에 가장 오래 있던 페이지를 교체.
  • 구현 단순하지만, 성능이 나쁠 수 있음.
  • Belady의 모순(Belady’s Anomaly): 프레임 수를 늘렸는데도 페이지 폴트가 증가할 수 있음.

(3) LRU (Least Recently Used)

  • 가장 오랫동안 사용하지 않은 페이지를 교체.
  • 과거 사용 이력이 미래 사용 가능성과 연관 있다는 "참조의 지역성(Locality)"에 기반.
  • 일반적으로 가장 널리 쓰임.
  • 구현 방식:
    • 카운터 기반 (최근 접근 시간 기록)
    • 스택 기반 (최근 사용된 페이지를 스택 상단에 유지)

(4) LFU (Least Frequently Used)

  • 사용 빈도가 가장 낮은 페이지를 교체.
  • 문제: 최근 집중적으로 쓰였지만 앞으로 필요 없는 페이지도 남아있을 수 있음.

(5) Clock 알고리즘 (Second Chance)

  • FIFO 변형: 교체 대상 페이지에 참조 비트(Reference Bit) 확인.
  • 참조된 페이지는 한 번 기회를 주고 다음 후보로 넘김.
  • 성능은 LRU에 근접하면서 구현은 단순.

4. 선택 기준

  • 실제 운영체제에서는 LRU 또는 Clock 알고리즘이 주로 사용.
  • 이유:
    • OPT는 이상적이지만 불가능.
    • FIFO는 성능 불안정.
    • LRU는 locality 가정 하에 안정적으로 좋은 성능.
    • Clock은 LRU 근사치로 구현 효율성 높음.

✅ 요약

  • 페이지 교체는 빈 프레임이 없을 때 어떤 페이지를 제거할지 결정하는 문제.
  • 목표: 페이지 부재율 최소화.
  • 대표 알고리즘: OPT, FIFO, LRU, LFU, Clock.
  • 실제 OS는 **LRU(또는 근사 알고리즘)**을 가장 많이 사용.

1. 쓰레싱(Thrashing)이란?

  • 과도한 페이지 부재(Page Fault) 때문에 CPU가 실제 작업보다 페이징 처리에 더 많은 시간을 소모하는 현상.
  • 결과적으로 CPU 이용률 급격히 저하, 시스템 성능이 심각하게 떨어짐.
  • 즉, 프로세스가 필요한 페이지가 메모리에 거의 없어서 계속 디스크 ↔ 메모리 스왑이 일어나는 상태.

2. 원인

  1. 메모리 과다 할당 부족
    • 프로세스들이 동시에 실행되면서 각 프로세스에 충분한 프레임을 배정하지 못한 경우.
  2. 지역성(Locality) 위반
    • 요구 페이징은 참조의 지역성을 가정하는데, 프로그램이 메모리 전체를 자주 건드리면 페이지 폴트 ↑.
  3. 다중 프로그래밍 정도(Multiprogramming Degree) 과도
    • 너무 많은 프로세스를 동시에 메모리에 올려두면 각 프로세스가 필요한 최소 프레임을 확보하지 못함.

3. 증상

  • 페이지 부재율(Page Fault Rate) ↑
  • CPU 이용률(CPU Utilization) ↓
  • 디스크 I/O 폭증
  • 프로그램 실행 속도 급격히 저하

4. 해결 방법

(1) 최소 프레임 보장

  • 각 프로세스에 필요한 최소 프레임 수를 보장해야 함.
  • 예: 페이지 교체 알고리즘과 함께 최소 프레임 개수를 할당.

(2) 작업 집합 모델 (Working Set Model)

  • 프로세스가 일정 시간 동안 자주 참조하는 페이지 집합 = 작업 집합(Working Set).
  • 이 집합을 모두 메모리에 적재 → 페이지 폴트 감소.

(3) PFF (Page Fault Frequency) 방식

  • 페이지 폴트율을 측정해 임계값 초과 시 → 프레임을 늘려주고, 낮으면 줄임.
  • 동적으로 프레임 수를 조절해 thrashing 방지.

(4) 다중 프로그래밍 정도 조절

  • 시스템에 동시에 실행되는 프로세스 수를 줄임.
  • 즉, 일부 프로세스를 swap-out 해서 나머지 프로세스가 충분한 프레임 확보하도록 함.

✅ 요약

  • Thrashing = CPU가 일 못 하고 페이징만 하는 상태.
  • 원인: 프레임 부족, 지역성 위반, 다중 프로그래밍 과도.
  • 해결: 최소 프레임 보장, 작업 집합(Working Set), PFF(Page Fault Frequency), 다중 프로그래밍 정도 조절.
반응형

'CS > 운영체제' 카테고리의 다른 글

fork 함수와 프로세스  (0) 2022.03.01
반응형

이전에 면접 준비하며 정리했던 내용 공유합니다.

📌 CORS란?

  • Cross-Origin Resource Sharing(교차 출처 리소스 공유)
  • 브라우저 보안 정책인 **SOP(Same-Origin Policy, 동일 출처 정책)**을 완화해주는 메커니즘
  • 기본적으로 브라우저는 다른 출처(origin)의 리소스 요청을 제한합니다.

👉 즉, CORS는 “다른 출처의 리소스를 클라이언트가 안전하게 요청할 수 있도록 서버가 허용하는 정책”이에요.

📌 CORS 동작 방식

  1. 단순 요청 (Simple Request)
    • 특정 조건 만족 시(예: GET/POST + 특정 헤더만) 브라우저가 바로 요청을 보냄
    • 서버가 응답 헤더에 Access-Control-Allow-Origin을 포함해야 함
    • 예:
    • Access-Control-Allow-Origin: <https://myapp.com>

📌 주요 헤더 정리

Access-Control-Allow-Origin: 허용할 출처 (* 또는 특정 도메인)

Access-Control-Allow-Methods: 허용할 HTTP 메서드

Access-Control-Allow-Headers: 허용할 요청 헤더

Access-Control-Allow-Credentials: 인증정보(쿠키, 토큰) 허용 여부

Access-Control-Max-Age: 프리플라이트 응답 캐시 시간

  1. 프리플라이트 요청 (Preflight Request)
  • 조건을 벗어난 요청(예: PUT, DELETE, 커스텀 헤더 포함)일 경우
  • 브라우저가 먼저 OPTIONS 메서드로 서버에 “이 요청 해도 되나요?” 물어봄
  • 서버가 허용하면 실제 요청 전송

예:

OPTIONS /api/data HTTP/1.1
Origin: <https://myapp.com>
Access-Control-Request-Method: PUT

서버 응답:

Access-Control-Allow-Origin: <https://myapp.com>
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type, Authorization

  1. Credential 요청 (쿠키/인증 포함)
    • fetch나 XHR에서 credentials: include 설정
    • 서버가 반드시 다음 헤더 필요:
    • Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: <https://myapp.com> (와일드카드 * 사용 불가)

🟦 OSI 7계층 구조

1. 물리 계층 (Physical Layer)

  • 역할: 데이터의 비트(0/1) 신호를 실제 전송 매체(케이블, 전파 등)를 통해 송수신.
  • 장비 예시: 허브, 리피터, 케이블, 커넥터
  • 단위: 비트 (Bit)

2. 데이터 링크 계층 (Data Link Layer)

  • 역할: 물리 계층에서 전송된 비트를 프레임(Frame) 단위로 관리. 에러 검출/수정, 흐름 제어 수행.
  • MAC 주소 사용 → 동일 네트워크 내에서 장치 식별.
  • 장비 예시: 스위치, 브리지
  • 단위: 프레임 (Frame)

3. 네트워크 계층 (Network Layer)

  • 역할: 데이터의 목적지까지의 경로 선택(라우팅), 논리적 주소(IP) 부여.
  • IP 주소 사용 → 다른 네트워크 간 통신 가능.
  • 프로토콜 예시: IP, ICMP, ARP, RARP
  • 장비 예시: 라우터
  • 단위: 패킷 (Packet)

4. 전송 계층 (Transport Layer)

  • 역할: 종단 간(end-to-end) 통신 제공. 데이터의 신뢰성 보장.
  • 주요 프로토콜:
    • TCP(연결지향, 신뢰성 보장, 흐름/혼잡 제어)
    • UDP(비연결성, 빠르지만 신뢰성 낮음)
  • 단위: 세그먼트 (TCP) / 데이터그램 (UDP)

5. 세션 계층 (Session Layer)

  • 역할: 통신 세션(대화)의 생성, 유지, 종료 관리.
  • 예: 로그인 세션, 원격 프레젠테이션 연결
  • 기능: 동기화, 체크포인트, 복구

6. 표현 계층 (Presentation Layer)

  • 역할: 데이터의 표현 방식 통일. 암호화, 압축, 인코딩/디코딩.
  • 예: JPEG, GIF, MP3, TLS/SSL 암호화
  • 키워드: 번역기 역할

7. 응용 계층 (Application Layer)

  • 역할: 최종 사용자와 직접 맞닿아 있는 계층. 네트워크 서비스 제공.
  • 프로토콜 예시:
    • HTTP/HTTPS (웹)
    • FTP (파일 전송)
    • SMTP/IMAP/POP3 (이메일)
    • DNS (도메인 네임 변환)

🔹 정리 (계층별 단위 & 장비)

계층 단위 주요 장비/기술

7. 응용 데이터 웹 브라우저, 앱
6. 표현 데이터 암호화/압축
5. 세션 데이터 API 세션 관리
4. 전송 세그먼트/데이터그램 TCP, UDP
3. 네트워크 패킷 라우터
2. 데이터링크 프레임 스위치
1. 물리 비트 케이블, 허브

 

 

 

애플리케이션 구조

📌 애플리케이션 구조 (Application Architecture)

애플리케이션 구조는 개발자가 설계한 방식에 따라 다양한 종단 시스템(End System)에서 애플리케이션이 어떻게 조직되는지를 설명한다.

대표적으로 클라이언트-서버 구조P2P 구조가 있다.


🔹클라이언트-서버 구조 (Client–Server Architecture)

  • 서버(Host): 항상 켜져 있고, 클라이언트의 요청을 처리하는 중심 시스템
  • 클라이언트(Client): 다수의 호스트에서 실행되며, 서버에 요청을 보내는 역할
  • 특징
    • 중앙 집중형 구조
    • 보안, 데이터 관리, 성능 최적화에 유리
    • 서버 부하가 집중되면 확장 비용 증가

🔹 P2P 구조 (Peer-to-Peer Architecture)

  • 특징
    • 항상 켜져 있는 기반 서버에 최소한만 의존
    • 피어(Peer): 간헐적으로 연결되는 호스트 쌍이 직접 서로 통신
    • 자가 확장성(Self-Scalability): 네트워크에 참여하는 피어 수가 늘어날수록 자원도 함께 증가
    • 탈 중앙화된 구조로 확장성과 유연성이 뛰어남

🔹 프로세스 (Process)

  • 정의: 종단 시스템에서 실행되는 프로그램 단위
  • 관심 대상: 프로세스 간 통신
    • 같은 종단 시스템 내부 프로세스 간 통신
    • 다른 종단 시스템 간 프로세스 간 통신
  • 클라이언트 & 서버 개념
    • 클라이언트(Client): 통신 세션을 초기화하는 프로세스
    • 서버(Server): 통신 세션을 시작하기 위해 접속을 기다리는 프로세스

✅ 요약하면,

  • 클라이언트-서버 구조는 중앙 집중형으로 관리가 용이하지만 서버 부하가 커짐
  • P2P 구조는 분산형으로 확장성이 뛰어나지만 관리와 보안이 상대적으로 복잡
  • 프로세스 관점에서는 누가 먼저 접속을 시도하는지(클라이언트)와 기다리는지(서버)에 따라 역할이 나뉨

📌 프로세스와 컴퓨터 네트워크 사이의 인터페이스

🔹 소켓 (Socket)

  • 정의: 애플리케이션과 네트워크 사이의 API
  • 역할: 프로세스가 네트워크를 통해 메시지를 주고받을 수 있도록 하는 인터페이스

🔹 애플리케이션 계층 프로토콜

  • 호스트 식별: 인터넷에서는 IP 주소로 호스트를 식별
  • 주요 요구 사항
    1. 신뢰적 데이터 전송
      • 손실 없는 데이터 보장을 원할 때: TCP
      • 손실 허용 애플리케이션(예: 스트리밍): UDP
    2. 처리량(Throughput)
    3. 보안(Security): SSL/TLS 계층에서 제공
  • 인터넷에서 대표적으로 사용되는 프로토콜
  • TCP, UDP (트랜스포트 계층)
  • HTTP (애플리케이션 계층)

📌 HTTP (HyperText Transfer Protocol)

  • 특징
    • 온-디맨드(On-Demand) 방식
    • 웹에서 사용하는 대표적 애플리케이션 계층 프로토콜
    • 기본적으로 TCP(HTTP/2.0 이하) 위에서 동작
    • 비상태성(Stateless) → 쿠키(Cookie)로 상태 관리 보완

🔹 HTTP 버전 별 특징

✅ HTTP 1.0

  • 비 지속 연결 (Non-Persistent Connection)
  • 요청–응답마다 TCP 연결을 새로 설정
  • 지속 연결 (Persistent Connection) 지원 시작

✅ HTTP 1.1

  • 기본적으로 지속 연결(Persistent)
  • Keep-Alive 헤더를 통해 연결 유지

✅ HTTP 2.0

  • 멀티플렉싱(Multiplexing): 하나의 연결에서 다중 요청/응답 처리
  • 성능 개선: 지연 감소, 헤더 압축, 서버 푸시(Server Push) 지원

** 하나의 TCP 연결을 통해 여러 데이터 요청을 병렬로 전송


✅ 요약하면,

  • 소켓은 프로세스와 네트워크의 인터페이스
  • TCP/UDP가 신뢰성과 속도의 기준을 결정
  • HTTP는 웹의 핵심 애플리케이션 프로토콜로, 버전 업그레이드마다 성능 최적화연결 효율성이 강화됨
  • 쿠키로 Stateless 한 HTTP를 보완

📌 웹 캐싱 (Web Caching)

🔹 정의

  • 웹 캐시(Web Cache, Proxy Server):
  • 웹 서버 대신 클라이언트의 HTTP 요청을 처리하는 네트워크 개체
  • 동작 원리:
    1. 브라우저가 요청한 객체(HTML, CSS, JS, 이미지 등)를 캐시에 저장
    2. 같은 요청이 다시 오면 원 서버(origin server)에 가지 않고 캐시에서 응답

🔹 특징

  • 성능 향상: 지리적으로 가까운 캐시 서버에서 응답 → 지연 시간 감소
  • 대역폭 절약: 동일 콘텐츠 반복 요청 시 원 서버로의 전송 감소
  • 부하 분산: 원 서버의 트래픽을 줄여 부하 완화
  • 운영 주체: 일반적으로 ISP(Internet Service Provider) 가 구입 및 설치

🔹 조건부 GET (Conditional GET)

웹 캐시가 저장된 객체가 여전히 최신인지 확인하기 위해 사용되는 HTTP 요청 방식

  1. ETag(Entity Tag)
    • 서버가 객체에 대해 생성하는 고유 식별자
    • 요청 시 If-None-Match 헤더로 전달
    • 서버는 ETag 비교 후 같으면 304 Not Modified 응답 → 캐시된 데이터 사용
  2. Last-Modified
    • 객체의 최종 수정 시간 정보를 제공
    • 요청 시 If-Modified-Since 헤더로 전달
    • 변경 없으면 304 Not Modified 응답

🔹 요청 흐름 요약

클라이언트 ──HTTP 요청──> 캐시 서버
             │
             ├─ 캐시에 있으면 → 바로 응답
             │
             └─ 캐시에 없거나 만료되면 → 원 서버에 요청
                                   │
                                   └─ 최신 여부 확인 (조건부 GET: ETag, Last-Modified)

✅ 정리하면,

  • 웹 캐시는 프록시처럼 동작하여 성능과 효율을 개선
  • 조건부 GET은 캐시된 콘텐츠의 유효성을 확인하는 핵심 메커니즘
  • 304 Not Modified 응답으로 불필요한 데이터 전송을 줄임

Cache-Control 헤더

🔹 정의

  • HTTP/1.1부터 도입된 캐싱 정책 제어 헤더
  • 서버가 응답 시 Cache-Control 헤더를 포함하면, 브라우저나 프록시 캐시가 리소스를 얼마나, 어떤 방식으로 캐싱할지 결정

🔹 주요 지시자(Directives)

1) 캐싱 가능 여부

  • public
    • 모든 캐시(브라우저, 프록시, CDN)에서 저장 가능
  • private
    • 특정 사용자 브라우저에서만 캐싱 가능 (공유 캐시 불가, 예: 개인화 페이지)
  • no-store
    • 아예 저장 금지 (민감 정보: 로그인, 금융 데이터)

2) 유효 기간

  • max-age=<초>
    • 리소스를 최대 n초 동안 신선한(fresh) 상태로 간주
    • 예: max-age=3600 → 1시간 동안 캐시 사용
  • s-maxage=<초>
    • 공유 캐시(CDN, 프록시)에만 적용되는 max-age
    • 브라우저 캐시에는 적용되지 않음
  • must-revalidate
    • 캐시 만료 후 반드시 원 서버에 검증 요청

3) 재검증 정책

  • no-cache
    • 저장할 수는 있지만, 재사용 전 반드시 원 서버 검증 필요
  • proxy-revalidate
    • 공유 캐시가 만료된 콘텐츠를 재사용할 때 반드시 서버 검증

4) 캐싱 우선순위 (HTTP/2 이상에서 활용)

  • stale-while-revalidate=<초>
    • 만료된 캐시라도 재검증 요청하는 동안 임시로 사용 가능
  • stale-if-error=<초>
    • 원 서버 에러 발생 시 만료된 캐시를 지정된 시간 동안 사용 가능

예시

1) 일반적인 정적 파일 (이미지, JS, CSS)

Cache-Control: public, max-age=31536000, immutable
  • public → 공유 캐시 가능
  • max-age=31536000 → 1년 캐싱
  • immutable → 파일이 변경되지 않는다는 가정 (버전 변경 시 파일명에 hash 사용)

2) 사용자 맞춤형 페이지

Cache-Control: private, no-store
  • private → 브라우저 캐시만 허용
  • no-store → 실제로는 캐시 불가 → 로그인 페이지, 결제 페이지 등에 사용

3) API 응답 (짧은 캐싱 허용)

Cache-Control: no-cache, must-revalidate, max-age=0
  • 저장은 가능하지만 매번 서버 검증 필요
  • 최신성이 중요한 JSON API 응답 등에 사용

🔹 정리

지시자 의미

public 모든 캐시 저장 가능
private 개인 브라우저만 저장 가능
no-store 저장 자체 금지
no-cache 캐시 가능하나 재사용 전 검증 필요
max-age=<초> 캐시 유효 시간 설정
s-maxage=<초> 공유 캐시 전용 유효 시간
must-revalidate 만료 후 반드시 서버 검증
stale-while-revalidate 만료 중에도 임시 사용 가능
stale-if-error 서버 에러 시 만료된 캐시 사용 가능

📌 메일 프로토콜 (Email Protocols)

🔹 SMTP (Simple Mail Transfer Protocol)

  • 역할: 메일 전송(송신) 프로토콜
  • 위치: 클라이언트 → 메일 서버, 메일 서버 → 메일 서버 간 전송
  • 특징
    • 푸시(push) 방식: 발신자가 수신자 메일 서버로 직접 전달
    • 전송 전용 → 수신에는 사용하지 않음
  • 포트
    • 기본: 25
    • 보안: 465(SSL), 587(TLS)

🔹 POP3 (Post Office Protocol v3)

  • 역할: 메일 수신(받기) 프로토콜
  • 특징
    • 메일 서버에서 클라이언트로 다운로드 후 → 기본적으로 서버에서 삭제
    • 단일 기기에서 사용하기 적합 (ex: PC Outlook에서만 확인)
  • 포트
    • 기본: 110
    • 보안: 995(SSL/TLS)

🔹 IMAP (Internet Message Access Protocol)

  • 역할: 메일 수신 및 관리 프로토콜
  • 특징
    • 메일 서버와 동기화 (서버에 메일 보관)
    • 여러 기기에서 동일 메일함 동기화 가능 (PC, 모바일, 웹메일)
    • 폴더 관리, 읽음/안읽음 상태 동기화 지원
  • 포트
    • 기본: 143
    • 보안: 993(SSL/TLS)

📊 비교 표

프로토콜 주요 역할 동작 방식 장점 단점

SMTP 메일 송신 클라이언트 → 서버, 서버 ↔ 서버 전송 표준 수신 불가
POP3 메일 수신 서버 → 클라이언트 (다운로드 후 삭제) 단순, 서버 부하 적음 여러 기기 동기화 불가
IMAP 메일 수신 서버 ↔ 클라이언트 동기화 다중 기기 동기화, 관리 용이 서버 저장 공간 차지

✅ 정리하면,

  • SMTP = 메일 보내기 (송신)
  • POP3 = 메일 받기 (다운로드, 단일 기기)
  • IMAP = 메일 받기 + 동기화 (멀티 기기, 서버 유지)

DNS

호스트에 대한 하나의 식별자 - 호스트네임(hostname)

  1. DNS는 DNS 서버들의 계층 구조로 구현된 분산 데이터베이스
  2. 호스트가 분산 데이터베이스로 질의하도록 허락하는 애플리케이션 계층 프로토콜

HTTP, SMTP, FTP등 사용자가 제공한 호스트 네임을 IP 주소로 변환하기 위해 주로 이용

모든 질의는 UDP로 보내짐

분산 데이터베이스

계층 형태로 구성되며 전세계에 분산됨

/** AI한테 도식 요구 **/

root (TLD, top level domain) 아래에 계단 식으로 DNS 서버 구성

TYPE A = 호스트 네임에 대한 IP 주소 제공

TYPE CNAME = 별칭 호스트네임에 대한 정식 호스트네임 제공

 

📌 트랜스포트 계층 (Transport Layer)

🔹 개요

  • 위치: 애플리케이션 계층 ↔ 네트워크 계층 사이
  • 역할: 다른 호스트에서 실행 중인 애플리케이션 프로세스 간의 논리적 통신 제공
  • 구현 위치: 종단 시스템(End System)
  • 기능
    • 트랜스포트 다중화(Multiplexing)
    • → 여러 애플리케이션 데이터 스트림을 하나의 네트워크 계층 연결로 전달
    • 역다중화(Demultiplexing)
    • → 받은 세그먼트를 올바른 애플리케이션 프로세스로 전달

🔹 UDP (User Datagram Protocol)

  • 특징
    • 비연결형(Connectionless) → 연결 설정/유지 X
    • 비신뢰성(Unreliable) → 패킷 손실, 순서 뒤바뀜 발생 가능
    • 혼잡 제어 X → 애플리케이션 계층이 직접 제어
  • 오류 검출
    • UDP 체크섬(Checksum)으로 종단 간 오류 검출 제공
  • 장점
    • 오버헤드 적음 (헤더 8바이트)
    • 빠른 전송에 적합 (스트리밍, DNS, 게임 등)

🔹 TCP (Transmission Control Protocol)

  • 특징
    • 신뢰성 있는 연결형 프로토콜(Connection-oriented)
    • 패킷 손실 시 재전송 보장
    • 흐름 제어, 혼잡 제어 제공
  • 데이터 전송 방식
    • 파이프라이닝(Pipelining): 다수 패킷을 연속적으로 전송
    • 슬라이딩 윈도우(Sliding Window) 프로토콜 기반
      • 수신 ACK을 받아 누적 확인 응답 사용 (Go-Back-N 방식)
      • 또는 개별 확인 응답 사용 (Selective Repeat 방식)

📌 신뢰적 데이터 전송: GBN vs SR

🔹 Go-Back-N (GBN)

  • 송신자는 윈도우 크기 N만큼 패킷 전송 가능
  • 누적 확인 응답(Cumulative ACK) 사용
    • ACK n = n까지 모든 패킷 정상 수신
  • 손실 발생 시
    • 손실 지점 이후 모든 패킷을 다시 전송
송신자: [1][2][3][4][5] ...
수신자: [1][2][X][4][5] ...
          └── ACK 2 (3번 손실)
송신자: 3 이후 패킷 모두 재전송
  • 장점: 구현 간단
  • 단점: 불필요한 재전송 많음

🔹 Selective Repeat (SR)

  • 송신자는 윈도우 크기 N만큼 패킷 전송 가능
  • 개별 확인 응답(Individual ACK) 사용
    • 각 패킷 별도로 ACK 전송
  • 손실 발생 시
    • 해당 패킷만 선택적으로 재전송
송신자: [1][2][3][4][5] ...
수신자: [1][2][X][4][5] ...
          ├── ACK 1
          ├── ACK 2
          ├── ACK 4
          └── ACK 5
송신자: [3]만 재전송

  • 장점: 불필요한 재전송 ↓ → 효율 ↑
  • 단점: 구현 복잡, 수신자는 out-of-order 패킷을 버퍼링해야 함

🔹 전송 프로토콜 비교

구분 UDP TCP

연결 방식 비연결형 연결형 (3-way handshake)
신뢰성 보장하지 않음 보장 (재전송, 순서 정렬)
흐름 제어 없음 있음
혼잡 제어 없음 있음
속도 빠름 상대적으로 느림
대표 사용처 DNS, VoIP, 스트리밍, 게임 웹(HTTP/HTTPS), 이메일(SMTP, IMAP), 파일 전송(FTP)

✅ 정리

  • UDP: 빠르고 단순, 하지만 신뢰성 없음 → 애플리케이션이 직접 보완해야 함
  • TCP: 신뢰성·순서·흐름 제어·혼잡 제어까지 제공하는 완전한 전송 프로토콜

TCP 연결 - 연결 지향형 프로토콜

  • TCP는 연결 지향형 프로토콜
  • 데이터 전송 전, 송·수신 양측이 논리적 연결(Connection)을 수립해야 함
  • 이 과정을 3-Way Handshake 라고 부름

🔹 3-Way Handshake 과정

1️⃣ SYN (synchronize)

  • 클라이언트 → 서버
  • 클라이언트가 연결을 요청하며 SYN 플래그 설정
  • 초기 시퀀스 번호(ISN, Initial Sequence Number)를 함께 보냄

2️⃣ SYN + ACK

  • 서버 → 클라이언트
  • 클라이언트의 SYN을 수락하고, 자신의 ISN과 함께 응답
  • SYN=1, ACK=1 플래그 설정

3️⃣ ACK (acknowledgement)

  • 클라이언트 → 서버
  • 서버의 SYN을 수락했다는 의미로 ACK를 전송
  • 이 시점에서 TCP 연결 수립 완료

🔹 흐름도 (간단 도식)

[Client]                                  [Server]
   | ----------- SYN(seq=x) -------------> |
   | <----- SYN(seq=y), ACK(ack=x+1) ----- |
   | -------- ACK(ack=y+1) --------------> |
   |                                       |
   |     [TCP Connection Established]      |


🔹 특징

  • 신뢰성 있는 연결 수립 (양쪽 모두 송수신 준비 완료 보장)
  • 3번의 왕복 메시지로 동기화 → 최소한의 오버헤드로 안정성 확보
  • 이후 데이터 전송(데이터 세그먼트 교환) 시작

3️⃣ TCP 연결 종료 (4-Way Handshake)

연결을 종료하고 싶은 host가 active closer, 종료 당하는 주체가 passive closer

  1. Active Closer → FIN 송신 (FIN_WAIT_1)
  2. Passive Closer → ACK 응답 (CLOSE_WAIT / Active=FIN_WAIT_2)
  3. Passive Closer → FIN 송신 (LAST_ACK)
  4. Active Closer → ACK 응답 후 TIME_WAIT 진입 → 종료

4️⃣ TIME_WAIT 상태

  • Active Closer가 마지막 ACK를 보낸 후 일정 시간(보통 2MSL, 30~60초) 대기
  • 이유:
    1. 지연 패킷 제거 (이전 연결 패킷이 새 연결에 섞이지 않도록)
    2. 마지막 ACK 보장 (ACK 손실 시 상대방의 FIN 재전송 처리 가능)

정리

  • 3-Way Handshake: TCP 연결 수립
  • ISN: 시퀀스 번호의 시작점, 순서·보안 보장
  • 4-Way Handshake: TCP 연결 종료
  • TIME_WAIT: 지연 패킷/ACK 손실 대비 안전 대기

📌 SSL/TLS Handshake 과정

핵심 아이디어:

  • *초기에는 비대칭 암호화(RSA, ECDHE 등)**를 사용해 "세션 키(대칭키)"를 안전하게 합의
  • *그 이후부터는 대칭 암호화(AES 등)**로 실제 데이터 통신 수행 (빠르고 효율적)

🔹 상세 단계 (TLS 1.2 기준 예시)

1️⃣ Client Hello

  • 클라이언트 → 서버
  • 클라이언트가 지원하는 암호화 알고리즘 목록, TLS 버전, 난수(Random) 전달

2️⃣ Server Hello + 인증서 전송

  • 서버 → 클라이언트
  • 서버가 사용할 암호화 알고리즘 선택
  • 서버 인증서(X.509, 공개키 포함) 전달

3️⃣ 인증서 검증

  • 클라이언트는 받은 서버 인증서를 CA(인증기관)의 공개키로 검증
  • 올바르면 서버의 공개키를 사용 가능

4️⃣ 세션 키 생성 & 전송

  • (RSA 방식일 경우)
    • 클라이언트가 **대칭키(Pre-Master Secret)**를 생성
    • 서버의 공개키로 암호화해서 서버로 전송
  • (Diffie-Hellman/ECDHE 방식일 경우)
    • 양쪽이 난수 교환을 통해 동일한 세션 키를 계산

5️⃣ 서버가 세션 키 복호화

  • 서버는 자신의 개인키(Private Key)로 클라이언트가 보낸 대칭키를 해독

6️⃣ Finished 메시지 교환

  • 서로 “이제부터 대칭키 암호화를 사용한다”는 신호 교환
  • 이후부터는 AES, ChaCha20 같은 대칭키 암호화로 통신

흐름 제어 (Flow Control)

🔹 개념

  • 송신자가 너무 많은 데이터를 빠르게 보내지 않도록 제어하는 메커니즘
  • 목적: 수신자의 버퍼 오버플로우 방지

🔹 TCP에서 흐름 제어 방식

  • 수신 윈도우(Receive Window, rwnd) 사용
  • 수신 측은 자신이 현재 얼마나 데이터를 더 받을 수 있는지를 rwnd 값으로 송신자에게 알려줌
  • 송신자는 이 윈도우 크기를 참고하여 데이터 전송량을 조절

🔹 동작 예시

  1. 수신 버퍼가 여유로움 → rwnd 크게 설정 → 송신자 많은 데이터 전송 가능
  2. 수신 버퍼가 가득 참 → rwnd=0 통보 → 송신자는 전송 중단
  3. 수신자가 버퍼를 비우면 → rwnd 갱신 → 송신자가 다시 전송 재개

🔹 특징

  • End-to-End 제어: 송신자 ↔ 수신자 간 직접 협력
  • 흐름 제어 ≠ 혼잡 제어
    • 흐름 제어: 수신자 능력에 맞게 제어
    • 혼잡 제어: 네트워크 상황에 맞게 제어

정리

  • TCP는 **수신 윈도우(rwnd)**를 통해 흐름 제어를 제공
  • 수신자가 처리 가능한 만큼만 데이터를 전송하게 만들어 버퍼 오버플로우 방지

📌 TCP 혼잡 제어 (Congestion Control)

네트워크 내 혼잡(패킷 손실, 지연)을 피하기 위해 송신자가 전송 속도를 조절하는 메커니즘.

핵심 개념은 **혼잡 윈도우(cwnd, Congestion Window)**를 유지하면서 네트워크 상황에 맞게 변화시키는 것.


🔹 1. 슬로 스타트 (Slow Start)

  • 처음 연결 시 cwnd = 1 MSS (최소 단위)로 시작
  • ACK를 받을 때마다 cwnd 두 배로 증가 (지수적 증가)
  • 너무 빠르게 늘어나므로 특정 임계값(ssthresh)에 도달하면 혼잡 회피 단계로 전환
cwnd: 1 → 2 → 4 → 8 → 16 ... (ACK마다 배 증가)


🔹 2. 혼잡 회피 (Congestion Avoidance)

  • cwnd가 ssthresh에 도달한 이후부터는 선형 증가 (1 MSS씩)
  • 네트워크를 과도하게 밀어넣지 않고 안정적으로 성장
cwnd: 17 → 18 → 19 ... (매 RTT마다 +1)


🔹 3. 빠른 재전송 & 빠른 회복 (Fast Retransmit & Fast Recovery)

(1) 빠른 재전송 (Fast Retransmit)

  • 같은 패킷에 대한 중복 ACK 3개를 받으면 손실로 판단 (슬라이딩 윈도우)
  • 타이머 만료 기다리지 않고 즉시 재전송

(2) 빠른 회복 (Fast Recovery)

  • 혼잡 발생 시 ssthresh = cwnd / 2 로 낮춤
  • cwnd도 절반으로 줄이고 → 이후 선형 증가(혼잡 회피 모드로)

🔹 동작 흐름 요약

  1. 슬로 스타트: 지수적 증가 (빠른 속도 확보)
  2. 혼잡 회피: 임계치 이후 선형 증가 (안정적 성장)
  3. 패킷 손실 발생
    • 타임아웃 발생 → cwnd = 1로 리셋, 다시 슬로 스타트
    • 중복 ACK 3개 → 빠른 재전송 + 빠른 회복

📊 그림으로 이해

혼잡 윈도우 크기 (cwnd)
│
│        /''''''''''''''''''' 혼잡 회피 (선형 증가)
│      /
│    /      ← 슬로 스타트 (지수적 증가)
│  /
│/________________________________ RTT


✅ 정리

  • 슬로 스타트: 빠른 시작 (지수적 증가)
  • 혼잡 회피: 네트워크 보호 (선형 증가)
  • 빠른 재전송 & 빠른 회복: 손실 시 즉시 대응, 성능 저하 최소화

 

링크 계층

 

🔹 ARP (Address Resolution Protocol)

  • 기능: IP 주소(논리 주소)를 실제 하드웨어 주소(MAC 주소)로 변환.
  • 이유: IP만 알면 목적지까지 경로를 잡을 수 있지만, 실제로 같은 네트워크에서 패킷을 보내려면 MAC 주소가 필요하기 때문.
  • 흐름:
    1. 송신자가 “이 IP 주소 가진 애 누구냐?” 하고 브로드캐스트 요청(ARP Request)을 보냄.
    2. 해당 IP를 가진 장치가 자기 MAC 주소를 알려줌(ARP Reply).
    3. 송신자는 이 매핑(IP ↔ MAC)을 ARP 캐시에 저장해 두고, 이후 재사용.

👉 즉, IP → MAC 변환.


🔹 RARP (Reverse Address Resolution Protocol)

  • 기능: 반대로, MAC 주소(물리 주소)만 알고 있을 때 IP 주소를 알아내는 프로토콜.
  • 사용 사례: 예전에는 디스크가 없는 얇은 클라이언트(디스크리스 워크스테이션)가 부팅할 때 자기 MAC은 알지만, IP는 몰라서 서버한테 “내 MAC은 이건데, 내 IP 좀 알려줘”라고 요청할 때 사용.
  • 흐름:
    1. 클라이언트가 RARP 요청(자기 MAC 주소 포함)을 브로드캐스트.
    2. RARP 서버가 해당 MAC에 맞는 IP를 응답으로 알려줌.
    3. 클라이언트는 그 IP를 사용해 네트워크 시작.

👉 즉, MAC → IP 변환.

 

 

📌 REST(Representational State Transfer)란?

  • 2000년 Roy Fielding 박사 논문에서 제안된 웹 아키텍처 스타일
  • 자원을 “URI로 표현”하고, 해당 자원에 대한 행위는 “HTTP 메서드”로 구분해 처리하는 방식

📌 RESTful API란?

  • REST 원칙을 잘 지켜 구현한 API
  • 즉, HTTP의 특징을 최대한 활용해 **일관적이고, 확장 가능하며, 무상태(stateless)**로 설계된 API

📌 RESTful API의 핵심 특징

  1. 클라이언트-서버 분리 (Client-Server)
    • UI와 데이터 저장/처리가 명확히 분리
  2. 무상태성 (Stateless)
    • 서버는 요청 간 상태(Session)를 유지하지 않음
    • 모든 요청은 필요한 정보를 자체적으로 포함해야 함
  3. 캐시 가능성 (Cacheable)
    • HTTP 캐시(Cache-Control, ETag) 등을 활용 가능
  4. 계층화 (Layered System)
    • 로드밸런서, 프록시, 게이트웨이 등을 중간에 껴도 동작 보장
  5. 인터페이스 일관성 (Uniform Interface)
    • URI로 자원을 식별하고, HTTP 메서드로 행위 표현
    • 예:
      • GET /users/1 → 사용자 조회
      • POST /users → 새 사용자 생성
      • PUT /users/1 → 사용자 전체 수정
      • PATCH /users/1 → 사용자 일부 수정
      • DELETE /users/1 → 사용자 삭제

📌 RESTful하지 않은 API 예시

  • GET /getUser?id=1 → ❌ 동작이 URI에 들어감
  • POST /updateUser/1 → ❌ 메서드와 URI 의미가 중복
  • GET /users/delete/1 → ❌ 조회 메서드(GET)로 삭제 동작

👉 RESTful API에서는 자원(Resource) 은 URI로, 행위(Action) 는 HTTP 메서드로 표현해야 함.


📌 면접 답변 예시

“RESTful API란, REST 아키텍처 스타일을 잘 지켜 구현한 API를 말합니다.

자원을 URI로 표현하고, HTTP 메서드로 행위를 구분하며, 서버는 무상태성을 유지합니다.

예를 들어 GET /users/1은 사용자 1 조회, DELETE /users/1은 사용자 1 삭제를 의미합니다.

이렇게 설계하면 API가 일관되고, 확장성과 재사용성이 높아집니다.”

📌 HATEOAS란?

  • HATEOAS (Hypermedia As The Engine Of Application State)
  • REST 아키텍처의 제약 조건 중 하나
  • 클라이언트가 서버와 상호작용할 때, 응답에 포함된 하이퍼미디어(링크)를 통해 다음 행동을 발견하도록 하는 원칙

📌 실무에서는?

  • 사실 많은 API가 “RESTful”이라고 하지만 HATEOAS까지 구현하지는 않음
  • 대부분은 Swagger/OpenAPI 문서로 엔드포인트를 공유하는 방식
  • HATEOAS는 Hypermedia API (예: HAL, JSON:API, Siren) 같은 규격에서 사용됨
  • 복잡한 클라이언트-서버 통신이나 동적으로 상태 변화가 많은 시스템에서는 유용하지만,
  • 단순 CRUD API에서는 오버엔지니어링일 수 있음

 

 

풀링/SSE/web socket

📌 1. Polling

  • 방식: 클라이언트가 주기적으로 서버에 요청(Are there any updates?) → 서버가 응답
  • 특징
    • 구현이 가장 단순 (기본 HTTP 요청/응답)
    • 하지만 불필요한 요청이 많음 → 네트워크/서버 리소스 낭비
    • 지연(latency)는 짧게 잡으면 실시간성이 있지만, 트래픽 비용↑

📌 2. SSE (Server-Sent Events)

  • 방식: 서버가 단방향으로 클라이언트에 지속적으로 이벤트를 푸시
    • 클라이언트는 EventSource 객체로 연결
    • 서버는 text/event-stream MIME 타입으로 메시지 스트림 전송
  • 특징
    • 단방향(서버 → 클라이언트)만 지원
    • HTTP/1.1 기반, TCP 위에서 동작
    • 자동 재연결, 이벤트 스트림 지원 (id, retry, event)
    • 브라우저 네이티브 지원 좋음
    • 한계: 양방향 통신 불가, 바이너리 데이터 전송 불편

📌 3. WebSocket

  • 방식: HTTP 연결을 업그레이드(Handshake) → 이후는 TCP 소켓 기반 양방향 통신
  • 특징
    • 양방향 통신 (서버 ↔ 클라이언트 모두 자유롭게 메시지 전송)
    • 헤더 오버헤드가 적어 효율적
    • 바이너리/텍스트 전송 모두 가능
    • 실시간 채팅, 게임, 주식 시세 스트리밍에 적합
    • 단점: 구현 복잡도↑, 인프라/보안/프록시 설정 주의 필요

📌 비교 표

구분 Polling SSE (Server-Sent Events) WebSocket

통신 방식 요청/응답 반복 서버 → 클라이언트 단방향 양방향 (Full-duplex)
프로토콜 HTTP HTTP (text/event-stream) HTTP Handshake → TCP
데이터 포맷 제한 없음 UTF-8 텍스트 텍스트 + 바이너리
브라우저 지원 전체 지원 최신 브라우저 대부분 지원 최신 브라우저 대부분 지원
사용 예시 알림 확인, 간단 주기 업데이트 뉴스 피드, 주가/날씨 알림 채팅, 게임, 실시간 협업
장점 단순 구현 자동 재연결, 브라우저 기본 지원 실시간 양방향, 효율적
단점 낭비 많음 단방향 한계, 바이너리 불편 구현/인프라 복잡도↑

📌 면접 답변 예시

“Polling은 클라이언트가 주기적으로 서버에 요청하는 방식이라 단순하지만 비효율적입니다.

SSE는 서버가 지속적으로 클라이언트에 이벤트를 보내주는 단방향 스트리밍으로, 알림/피드 업데이트에 적합합니다.

WebSocket은 HTTP 연결을 업그레이드해서 양방향 통신을 지원하며, 채팅이나 게임 같이 빠른 상호작용이 필요한 서비스에 많이 쓰입니다.”

반응형

'CS > 네트워크' 카테고리의 다른 글

AnyCast란?  (0) 2022.04.11
URL & URI & URN  (0) 2022.02.27
HTTP 메소드 멱등성, 안전한 메소드  (0) 2022.01.31
[TCP] 3-way handshake와 4-way handshake  (0) 2022.01.23
Pooling, Long Pooling, Streaming  (0) 2022.01.23
반응형

가끔 공부하다보면 anycast란 내용이 보이길래 요약겸 정리해논다.

 

Anycast

Anycast는 각각 동일한 IP 주소가 할당된 엔드포인트 그룹에 여러 라우팅 경로를 제공하는 기술 - microsoft

 

??? 이렇게 말하면 무슨 말인지 감이 잡히지 않는다.

 

보통 우리가 알고 있는 IP는 '고유한' 주소이고, Unicast IP이다. 

우선 unicast가 뭔지 알고 넘어가야 될꺼 같다.

 

참고)

그림 출처 : https://microchipdeveloper.com/tcpip:tcp-vs-udp

유니캐스트 (Unicast) - 1 : 1 

유니캐스트는 정보를 전송하기 위한 프레임에 자신의 MAC 주소와 목적지의 MAC 주소를 첨부하여 전송

 

브로드캐스트 (Broadcast) 1 : N

브로드캐스트 방식은 로컬 네트워크에 연결되어 있는 모든 시스템에게 프레임을 보내는 방식

 

멀티캐스트(Multicast) 1: N (특정 그룹)

멀티캐스트는 네트워크에 연결되어 있는 시스템 중 일부에게만 정보를 전송하는 것으로 특정 그룹에 속해 있는 시스템에게만 한 번에 정보를 전송할 수 있는 방법

라우터가 멀티캐스트를 지원해야만 사용 가능하다는 단점

멀티캐스트 전송이 지원되면 송신자는 여러 수신자에게 한 번에 메시지가 전송되도록 하여

데이터의 중복 전송으로 인한 네트워크 자원 낭비를 최소화할 수 있게 된다.

멀티캐스트 전송을 위해서는 헤더에 수신자의 주소 대신 수신자들이 참여하고 있는 그룹 주소를 표시하여 패킷을 전송한다.

 

Anycast란?

 

Anycast IP는 서로 다른 호스트끼리 동일한 IP 주소를 가질 수 있는 개념이다.

 

링크 계층(L2)에서 맥 주소를 보고 데이터를 전달할때는 충돌이 일어나면 사용이 불가능하지만

라우터(L3)에서는 네트워크 라우팅 알고리즘(BGP)을 통해 가장 가까운곳으로 판단되는 쪽으로 사용 가능한 식으로 구현되어 있다. 

 

anycast는 주로 DNS 서비스에 많이 활용되고 있다는데 지역별로 DNS 서버를 분산하고, 항상 네트워크 경로상 가까운 DNS 서버가 응답하게 된다.

 

왜 이런 구조를 사용하냐면 root DNS에 하위 DNS 서버들이 계층적으로 쌓여있는 기존 구조에서는 네트워크 DNS DDos 공격이나 웜 공격등으로 root DNS가 마비되게 되면 전 세계 DNS가 마비되게 된다. 그래서 DNS를 적절히 분산 구성해 분산 처리 및 가까운 거리로 인한 네트워크 지연 감소 등 여러 이유로 사용하고 있다고 한다.

 

가장 유명한 예시로는 구글의 public DNS IP 8.8.8.8 이 anycast로 구성되어 있고,

전세계 국가에 분산되어 있다고 한다. 

 

장점

- L4/L7 로드밸런싱 장비 대신 쓰기 가능?(라우팅+서버)

- 사용자와 네트워크 적으로 가장 가까운 곳으로 안내

- L4/L7 이 대규모 트래픽 처리가 힘든데 서버로 바로 트래픽을 보내니 대규모 트래픽 처리에 용이

- 회선문제로 장애시 자동으로 다른곳으로 우회(회선 이중화 비용 절감)

- 오픈소스 -> 가격 X!

 

단점

- 네트워크 적으로 가장 가까운곳 !== 지리적으로 가까운곳

ISP 마다 라우팅 정책이 다르므로 제어가 힘들다.

- 라우터에서 라우팅만 하기 때문에 L4/L7에선 가능한? 서버의 상태 체크(죽었나 살았나)가 안된다는 단점

 

reference 

 

https://docs.microsoft.com/ko-kr/windows-server/networking/dns/deploy/anycast

 

Anycast DNS 개요

이 항목에서는 Anycast DNS에 대한 간략한 개요를 제공합니다.

docs.microsoft.com

 

https://tech.kakao.com/2014/05/29/anycast/

 

kakao의 Anycast 활용 사례

Overview 네트워크 기술 하나 중 Anycast 는 DNS 서비스에서 주로 사용하고 있지만 KAKAO는 Anycast 기술을 확장하여 여러가지 어플리케이션 서비스에 사용되고 있습니다. 특히 서버에서 Quagga 오픈소스를

tech.kakao.com

 

반응형

'CS > 네트워크' 카테고리의 다른 글

네트워크 관련 정리  (0) 2025.09.29
URL & URI & URN  (0) 2022.02.27
HTTP 메소드 멱등성, 안전한 메소드  (0) 2022.01.31
[TCP] 3-way handshake와 4-way handshake  (0) 2022.01.23
Pooling, Long Pooling, Streaming  (0) 2022.01.23
반응형

프로세스를 새로 생성할때 fork 함수를 이용할 수 있습니다.

 

fork 함수를 호출한 프로세스는 부모 프로세스가 되고

새롭게 생성되는 프로세스는 자식 프로세스가 됩니다.

두 프로세스는 다른 pid를 가지고 독립적이게 동작합니다.

Copy On Write

 

부모 프로세스가 자식 프로세스를 생성(fork)한 직후 프로세스와 메모리 모습

이때 Linux에서는 자식 프로세스를 생성하면 같은 메모리 공간을 공유하게 됩니다. 

부모 프로세스에서 페이지 바로 C를 수정한다면 자식 프로세스에도 영향을 끼칠것입니다.

 

그래서 직접 변경 대신 페이지 C를 복사해서 수정(Copy on write)하는 방식으로 작동합니다.

 

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<fcntl.h>

int statofLoc; // get child process's state when child process is done
int childPid;

char **command; //get parsed words, command[0] is command,  
                //others option

void fatal_error(char* errorCommand) // to record error and exit
{
  perror(errorCommand);
  exit(-1);
}

childPid = fork();

if(childPid == 0){ // child
			
   if(execvp(command[0], command)<0)
  {
    fatal_error("unknown command");
    //if this function is actived,
    //something is wrong
  }
}
else if(childPid < 0) //error
{
  fatal_error("pid ERROR");
}
else //parent
{
  waitpid(childPid, &statofLoc, WUNTRACED);
  //wait till child process is done.
}

 

wait(혹은 waitpid) 함수를 이용하면 부모 프로세스는 자식 프로세스가 종료될때까지 기다릴 수 있습니다.

 

wait는 다음과 같이 작동합니다.

 

1. 자식 프로세스가 동작 중이면 호출 차단이 차단되기 때문에 상태를 얻어올 때까지 대기

2. wait() 함수 호출자가 시그널을 받을 때까지 대기

3. 자식 프로세스가 종료된 상태라면 즉시 호출이 반환되어 상태를 얻음, 이 때 wait() 함수는 자식 프로세스의 프로세스 ID를 반환
4. 자식 프로세스가 없다면 호출이 즉시 반환되며, 에러값을 반환

 

고아 프로세스  

 

부모가 먼저 자식 프로세스보다 먼저 종료되면 자식 프로세스는 고아 프로세스가 됩니다.

 

만약 부모가 먼저 종료되면 커널은 부모 프로세스가 누구의 부모인지 확인하고 자식 프로세스들의 부모 프로세스 ID

(ppid)들을 전부 1(init process)로 바꿔줍니다.

 

리눅스에서 백그라운드에서 돌아가는 데몬 프로세스를 생성하는 방법으로 해당 방식을 이용합니다.

1. fork후 부모 종료(ppid 가 1로 변경)

2. setsid로 고아 프로세스를 세션 리더로 생성

3. etc...

 

고아 프로세스가 종료되면 init process가 wait를 호출해 좀비 프로세스가 되는것을 방지합니다.

좀비 프로세스

 

자식 프로세스가 종료되었지만 자식 프로세스의 종료상태를 회수하지 않았을때 자식 프로세스를 좀비 프로세스라 합니다.

 

자식 프로세스가 exit 시스템콜을 호출하면 프로세스에 대한 메모리 & 리소스가 해제되 다른 프로세스에서 사용 가능합니다.

그런데 자식 프로세스의 정보를 알고 싶어할 수 있기 때문에 부모 프로세스의 wait system call 호출 이전까지는 최소한의 정보를 가지는 상태로 남아 있습니다. 

wait로 정말로 제거되기 이전 상태를 좀비 프로세스라고 부릅니다. 

 

 

그럼 fork를 어디에 쓰나요..? 보통 멀티테스킹을 위해 많이 쓰입니다.

대표적인 예시로는 shell에서

 

터미널에서 fork 해 자식 프로세스를 만든 다음

자식 프로세스에서 명령어를 파싱하고, exec system call을 해 명령을 처리합니다.

 

다만 cd(change directory)의 경우 자식 프로세스가 아니라 부모 프로세스(터미널) 자체가 움직여야 하기 때문에

cd는 예외적으로 fork를 하지않고 직접 처리합니다.

 

reference

 

COW

https://openwiki.kr/tech/copy-on-write

 

Copy-on-write - 기술 - 오픈위키

Copy-on-write Copy On Write란 말 그대로 작성시 이전의 내용을 Copy한다는 뜻이다. 1) Linux(Unix)에서는 자식 프로세스(child process)를 생성(fork)하면 같은 메모리 공간을 공유하게 된다. 그런데 부모 프로세

openwiki.kr

 

https://codetravel.tistory.com/30?category=993122 

 

wait 함수 사용하여 자식 프로세스 종료시까지 대기하기

부모 프로세스가 fork() 함수를 사용하여 자식 프로세스를 생성하였을 때, fork() 함수가 리턴되는 시점부터 2개의 프로세스가 동작하게 됩니다. 부모 프로세스가 자식 프로세스의 종료 상태를 얻

codetravel.tistory.com

데몬 프로세스

https://kukuta.tistory.com/386

 

[Linux] 데몬(Daemon) 프로세스 만들기

데몬(daemon)이란? '데몬(daemon)' 프로세스는 리눅스 운영 체제서 사용하는 프로세스의 일종으로써, 시스템 시작이 시작할 때 그 생명을 시작하여, 우리가 알지 못하는 백그라운드에서 자신의 할 일

kukuta.tistory.com

 

반응형

'CS > 운영체제' 카테고리의 다른 글

운영체제 관련 정리  (1) 2025.09.29
반응형

엄청 헷갈리는 개념이라 메모해두려고 한다.

 

 

URI (Uniform Resource Identifiter - 통합 자원 식별자)

 

웹 기술에서 사용하는 논리적 or 물리적 리소스를 식별하는 고유한 문자열 시퀀스

주소보다는 '식별자'의 개념

 

URL (Uniform Resource Locator)

 

네트워크 상에서 웹 리소스에 대한 참조

흔히 웹 주소라고 한다.

우리가 주로 쓰는 주소가 URL

 

URL은 URI의 서브셋이다.

URI - 식별자

URL - 위치

 

 

URN (Uniform resource name)

 

URI의 특정 포맷중 하나로 이름으로 리소스를 특정하는 URI 

프로토콜을 제외하고 리소스의 name 을 가리키는데 사용

URN에는 접근 방법 & 위치가 표기 X

 

 

참고) URL 구조

 

scheme:[//[user[:password]@]host[:port]][/path][?query][#fragment]

 

scheme : 사용할 프로토콜을 뜻하며 웹에서는 http 또는 https를 사용

user와 password : (서버에 있는) 데이터에 접근하기 위한 사용자의 이름과 비밀번호

host와 port : 접근할 대상(서버)의 호스트명과 포트번호

path : 접근할 대상(서버)의 경로에 대한 상세 정보

query : 접근할 대상에 전달하는 추가적인 정보 (파라미터)

fragment : 메인 리소스 내에 존재하는 서브 리소스에 접근할 때 이를 식별하기 위한 정보

 

reference

 

https://www.charlezz.com/?p=44767 

 

URI랑 URL 차이점이 뭔데? | 찰스의 안드로이드

URI 그리고 URL을 혼용해서 사용하는 경우가 있다. 대부분의 경우 문제가 없지만 정확하게 이 둘의 차이점이 존재한다. 그러므로 각 용어의 정의와 용도에 대해서 알아본다. URI URI는 특정 리소스

www.charlezz.com

 

https://mygumi.tistory.com/139

 

URI vs URL vs URN :: 마이구미

이번 글은 URI, URL, URN 을 다뤄본다. URI와 URL은 아직도 많이 혼동되고 있다. 우리는 대부분 URL이라는 표현을 하고 있다. 우리가 보고 있고, 사용하고 있는 대부분이 사실 URL이기 때문이다. URI, URL, U

mygumi.tistory.com

 

반응형

'CS > 네트워크' 카테고리의 다른 글

네트워크 관련 정리  (0) 2025.09.29
AnyCast란?  (0) 2022.04.11
HTTP 메소드 멱등성, 안전한 메소드  (0) 2022.01.31
[TCP] 3-way handshake와 4-way handshake  (0) 2022.01.23
Pooling, Long Pooling, Streaming  (0) 2022.01.23
반응형

개인적으로 DB 내용은 어렵기도 하고 안쓰고 있으면 자꾸 까먹는거 같습니다.

이 블로그의 주 목적이기도 하고 메모용으로 간단하게 글을 써보려 합니다.

 

*틀린게 있으면 피드백 주시면 감사하겠습니다!

 

index란?

 추가적인 쓰기 작업과 저장 공간을 활용하여 데이터베이스 테이블의 검색 속도를 향상시키기 위한 자료구조

1000페이지의 책이 있다고 쳐봅시다. 특정 키워드를 찾고 싶은데 1쪽부터 1000쪽까지 전부 순회하며 찾으려면 매우 큰 시간 낭비일것입니다.

 

그래서 책에는 키워드를 빨리 찾기 위해서 보통 맨뒤에 색인이 있습니다.

데이터베이스에서도 인덱스는 책의 색인과 비슷한 역할을 한다고 보면 좋습니다.

 

(보통 Index는 PK에 기본적으로 걸려있습니다.)

 

Index의 구조

 

Balanced Tree인 B+(B) tree를 많이 사용합니다.

 

A: 트랙 B: 기하학적 섹터 C: 트랙 섹터 D: 클러스터

왜 tree 형태냐면 하드 디스크에서 데이터를 가져올때 섹터 단위(block 단위)로 가져오게 되는데 데이터를 효율적으로 관리하기 위해서 포인터로 참조하는 트리 형태를 띄게 됩니다.

 

*  b tree는 모든 노드에 key와 데이터를 가지지만 B+ tree는

branch node에서는 leaf node에 대한 key를 가지고, leaf node에만 데이터를 가집니다. 

 

Index의 장점

 

- 테이블 조회 속도 & 성능 향상

- 시스템 부하 감소

 

Index의 단점

 

- 인덱스를 사용하기 위해 대략 10%의 추가 저장공간이 필요하다

- 잘못 사용할 경우 성능 저하

- index 관리를 위해 추가 작업 필요 

 

보통 create, update, delete는 빈번하게 일어나지 않고 조회(select)만 자주 일어나는 속성에 사용하는게 좋습니다

-> DELETE, UPDATE 시 인덱스를 '사용하지 않음' 처리 

빈번하게 DELETE, UPDATE가 일어난다면 인덱스의 크기가 매우 커져서 오히려 성능이 줄어든다.

 

* select문에서 like '%문자' 같이 %를 앞에 넣어서 사용하는 경우 index를 타지않아서

검색 구현시 형태소 분석이나 elasticsearch를 사용하는것을 권장한다고 합니다

 

사용하면 좋은경우 

 

- 규모가 매우 큰 테이블

- INSERT, UPDATE, DELETE가 빈번하지 않은 컬럼

- 자주 SELECT문(특히 join, where, order by)에 쓰이는 컬럼

- 데이터의 중복도가 낮은(=cardinality가 높은) 테이블

- 데이터 분포도 10~15%(1/해당 컬럼의 distinct 데이터 개수 * 100)인 칼럼

 

Cardinality란?

 

전체 행에 대한 특정 컬럼의 중복 수치를 나타내는 지표입니다

 

-> 중복도 낮다 = 카다널리티 높다.

-> 중복도 높다 = 카다널리티 낮다.

 

중복도는 어떤 절대적인 수치가 아니라 '상대'적인 수치입니다.

id name location
1 park seoul
2 lee seoul
3 park busan
4 kim busan

 

id가 distanct값이 4개이므로 가장 카다널리티가 높습니다.

name은 distant 값이 3개이므로 id보다는 카다널리티가 낮고, location보다는 카다널리티가 높습니다.

location은 distant 값이 2개이므로 가장 카다널리티가 낮습니다.

 

인덱스를 걸때 중복이 최대한 없어야 데이터가 많이 걸러질것입니다. (중복이 많을수록 full scan에 가까워짐)

그래서 카다널리티가 높은 컬럼을 인덱스 우선순위로 추천한다고 합니다. 

 

Clustered Index 

 

Index를 생성할때 데이터 페이지 전체를 물리적으로 재배열 합니다.

 

테이블 당 한개만 존재합니다.

-> 가장 효율적인 칼럼을 Clustered Index로 지정 

테이블 크기의 3%정도 추천

 

Non-Clustered Index

 

군집화 되어있지 않은 인덱스 타입? (순서대로 정렬되있지 않다)

물리적으로 데이터를 배열하지 않고, 별도의 장소에 데이터 페이지가 구성됩니다.

테이블 당 여러개 존재 가능합니다.

 

Non-clusered index는 clustered Index보다 검색 속도는 느리지만 입력/수정/삭제는 더 빠릅니다.

(clustered Index의 경우 그 반대)

테이블 크기의 20%정도 추천

 

reference 

 

index 

 

https://mangkyu.tistory.com/96

 

[Database] 인덱스(index)란?

1. 인덱스(Index)란? [ 인덱스(index)란? ] 인덱스란 추가적인 쓰기 작업과 저장 공간을 활용하여 데이터베이스 테이블의 검색 속도를 향상시키기 위한 자료구조이다. 만약 우리가 책에서 원하는

mangkyu.tistory.com

 

b tree 

 

https://velog.io/@seanlion/btree

 

B트리,B+트리, B*트리 개념 정리

오늘은 트리 종류 중 하나인 B트리 시리즈를 정리해보려고 합니다. 이 포스팅에서는 B트리 시리즈 개념에 대해서 다룹니다.

velog.io

 

카디널리티

 

https://itholic.github.io/database-cardinality/

 

[database] 카디널리티(cardinality)란?

cardinality

itholic.github.io

 

반응형
반응형

수학적으로 멱등성이란

어떤 집합이 연산 A에 대해 닫혀있을때, 연산 A를 여러번 적용해도 달라지지 않는 성질을 뜻한다.

 

네트워크 HTTP 에서 멱등성이란

동일한 요청을 한 번 보내는 것과 여러 번 연속으로 보내는 것이 같은 효과를 지니고,

서버의 상태도 동일하게 남을 때, 해당 HTTP 메서드가 멱등성을 가졌다고 말한다.

 

다만 서버가 REST API를 잘 따랐다는 전제하에 멱등성 제약이 보장된다.

(ex : 서버가 get으로 CRUD 전체를 다 처리한다던가 restful하지 않게 구현되어 있다면 멱등성 보장 X)

멱등성이 성립하는 기준

 

멱등성은 요청의 효과를 보고 판단한다.

같은 행위를 여러번 반복하더라도 같은 효과를 가져야한다.

 

많이 쓰이는 http method중 POST를 제외한 GET, PUT, DELETE 가 멱등성이 보장되고,

그외 method로는 OPTIONS, HEAD 등이 있다.

 

예를 들어 PUT의 경우

 

PUT /user/4

 

라는 요청이 간다면 4번째 유저가 없다면 생성되고, 있다면 update 되는 형식으로 동작할것이다.

그런데 PUT 요청을 여러번 보내더라도 항상 4번 유저는 요청된 값과 똑같은 값으로 갱신하니

같은 상태일 것이다.

 

DELETE도 비슷한 방식으로 동작하고, GET, OPTIONS, HEAD 같은 경우는 조회(read) 동작만 하므로

항상 서버의 상태는 동일하다고 기대할 수 있다.

 

다만 PATCH(리소스의 일부만 수정)의 경우 멱등성이 보장이 되지 않는다.

예를 들어

 

PATCH users/1
{
    $increase: 'age',
    value: 1,
}

 

같이 increase하고 싶은 변수 이름과 값을 보낸다고 해보자.

그럼 PATCH를 보낼때마다 상태가 변경되니 멱등성을 기대할 수 없다고 볼 수 있다.

 

안전한 메소드

 

그럼 안전한 메소드란?

 

서버의 상태를 아예 변경시키지 않는 메소드를 말한다.

해당 메소드로는 GET, OPTIONS, HEAD 등 read 메소드들이 있다

 

 

https://velog.io/@dion/HTTP-%EB%A9%94%EC%86%8C%EB%93%9C%EC%9D%98-%EB%A9%B1%EB%93%B1%EC%84%B1-%EA%B7%B8%EA%B2%8C-%EB%AD%94%EB%8D%B0

 

HTTP 메소드의 멱등성? 그게 뭔데?

멱등성이 무엇인지 알고계신가요? 멱등성이란, 수학에서 사용하는 용어에서 유래한 것으로. 연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질을 뜻합니다.이 멱등성은 왜 HTTP Method와 연

velog.io

https://oen-blog.tistory.com/211

 

[ RESTful API] PUT과 PATCH의 차이 - 멱동성을 보장하는 PUT, 멱등성을 보장하지 않는 PATCH

PUT 메소드는 반드시 멱등성을 보장하지만 PATCH 메소드는 멱등성을 보장하지 않을 수도 있다. 멱등성이란 멱등성이란 어떤 대상에 같은 연산을 여러번 적용해도 결과가 달라지지 않는 성질 이다.

oen-blog.tistory.com

 

https://developer.mozilla.org/ko/docs/Glossary/Idempotent

 

멱등성 - 용어 사전 | MDN

동일한 요청을 한 번 보내는 것과 여러 번 연속으로 보내는 것이 같은 효과를 지니고, 서버의 상태도 동일하게 남을 때, 해당 HTTP 메서드가 멱등성을 가졌다고 말합니다. 다른 말로는, 멱등성 메

developer.mozilla.org

 

반응형

'CS > 네트워크' 카테고리의 다른 글

네트워크 관련 정리  (0) 2025.09.29
AnyCast란?  (0) 2022.04.11
URL & URI & URN  (0) 2022.02.27
[TCP] 3-way handshake와 4-way handshake  (0) 2022.01.23
Pooling, Long Pooling, Streaming  (0) 2022.01.23
반응형

폰 노이만 구조

현재와 같은 CPU, 메모리, 프로그램 구조를 갖는 범용 컴퓨터 구조의 확립

 

  • 산술 논리 장치와 프로세서 레지스터를 포함하는 처리 장치
  • 명령 레지스터와 프로그램 카운터를 포함하는 컨트롤 유닛
  • 데이터와 명령어를 저장하는 메모리
  • 외부 대용량 스토리지
  • 입출력 매커니즘

장점 

컴퓨터에 작업을 시키려고 할때 하드웨어적으로 재 배치를 할 필요가 없이 소프트웨어만 교체하면 되기 때문에

범용성(general-purpose)이 크게 향상된다.

따라서 현대의 컴퓨터는 거의 다 이 구조를 따르고 있다.

 

단점

메모리에서 데이터/코드(프로그램)을 가져올때 버스 하나로 한번에 하나만 가져오는 구조이기 때문에 폰 노이만 병목 현상이 일어날 수 있다.

이를 해결하기 위해 다양한 방법이 고안되었지만 폰 노이만 구조를 쓴다면 근본적 문제는 해결하진 못했다.

 

- 하버드 구조의 발명 

- 메모리 계층 구조(L1~L2 캐시, 메인 메모리, 하드디스크 구조)

- 다양한 방식 고안

ex) NUMA(메모리에 접근하는 시간이 메모리와 프로세서간의 상대적인 위치에 따라 달라진다.)

DMA(CPU가 직접 메모리 접근)

 

 

하버드 구조

하버드 아키텍처(Harvard architecture)는 명령용 버스와 데이터용 버스로 물리적으로 분할한 컴퓨터 아키텍처

명령용 버스와 데이터용 버스를 분할 -> 폰 노이반 병목 현상을 동시 접근으로 해결하려고 시도

 

단점 : cost(버스가 2배!)

 

현대에 이르러서는 CPU의 외부적으로는 폰 노이만 구조를, 내부적으로는 하버드 구조

 

reference

 

https://velog.io/@ckstn0777/%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0

반응형

'CS > 컴퓨터구조' 카테고리의 다른 글

[컴퓨터 구조] cache, Write Through과 Write Back  (0) 2022.01.23
반응형

 

캐시란?

 

자주 사용하는 데이터나 값을 미리 복사해 놓는 임시 장소를 가리킨다. 캐시는 저장 공간이 작고 비용이 비싼 대신 빠른 성능을 제공한다. 

 

Cache는 아래와 같은 경우에 사용을 고려하면 좋다.

  • 접근 시간에 비해 원래 데이터를 접근하는 시간이 오래 걸리는 경우(서버의 균일한 API 데이터)
  • 반복적으로 동일한 결과를 돌려주는 경우(이미지나 썸네일 등)

캐시는 컴퓨터 구조뿐만 아니라 네트워크, DB등 여러곳에서 자주 사용하는 개념이다.

이글에서는 CPU 내부의 캐시에 대해 간략하게 알아본다.

 

CPU 캐시 란

 

cpu의 내부 캐시란 CPU와 메인 저장 장치(하드디스크)간 속도의 모순을 해결하기 위해서 사용하는 것이다.

 

CPU 는 종종 동일한 데이터를 반복적으로 처리하고, 실행하는데(지역성) 그때마다 메모리에서 받아와 처리한다면 

비교적 느린 하드디스크에서 데이터를 받아올때마다 CPU는 기다리는 오버헤드가 발생하게 된다.

 

그래서 CPU 내부에 일종의 저장 장소(SRAM)를 가지고 캐싱해놓게 되는데 그것을 캐시라 한다.

 

L1, L2, L3 캐시 메모리등이 있는데

숫자가 작을수록 작고 비싸고, 빠르고 CPU 내부에서 가장 가까운 곳에 위치해 있다고 보면 된다.

 

그리고 cache를 제어하는 방식에 대해 간단히 알아보자.

 

write-Through

CPU가 데이터를 사용하면 캐시에 저장되게 되는데, 데이터가 캐시 됨과 동시에 주기억장치 또는 디스크로 기입되는 방식을 지원하는 구조의 캐시이다. 즉, 캐시와 메모리 둘다에 업데이트를 해버리는 방식이다.

 

다만 업데이트때마다 직접 하면 cost가 비싸므로 

Write buffer라는 구조를 사용해서 CPU 프로세서가 직접 Write 명령을 수행하지 않아 대기하는 시간을 줄여주는 방식으로 작동한다고 한다. (이건 write Back에도 사용 가능)

 

write-Back

 데이터를 쓸 때 메모리에는 쓰지 않고 캐시에만 업데이트를 하다가 필요할 때에만 주기억장치나 보조기억장치에 기록하는 방법이다.

 

그럼 캐싱을 사용하면 안될때는 언제일까?

C언어, Java에서는 volatile 명령어로 캐싱을 사용하지 않고 메인메모리에서 접근해서 가져오도록 사용 가능하다.

volatile int num1 = 10;    // 변수를 최적화에서 제외하여 항상 메모리에 접근하도록 만듦
public class SharedObject {
    public volatile int counter = 0;
}

 

그럼 이것을 언제 사용할까?

캐시는 지금까지 좋다고 글을 썼는데 왜 캐시를 안쓰고 굳이 메인 메모리에서 값을 가져올까?

그 답은 아래 그림처럼 멀티 CPU 상황일경우 임계영역인 데이터의 동기화를 위해 쓴다고 볼 수 있다.

 

혹은 임베디드 프로그래밍에서 인터럽트 내부에서 메모리의 어떤 값이 수정되었는데 CPU 내부의 캐시는 수정되지 않았을때를 방지하려고 volatile 예약자를 쓴다. 

 

읽어보면 좋을 글)

https://blog.naver.com/cjsksk3113/222253156868

 

캐시 일관성(Cache Coherence)과 캐시 속성(Cacheable / Non Cacheable)

캐시 메모리 요즘의 CPU 주기억장치 메모리(Main Memory)는 거의 100% SDRAM으로 구성된다. SD...

blog.naver.com

 

reference 

 

https://itgall.com/hardware/232948

 

CPU 캐시가 L1, L2 및 L3으로 나뉘는 이유에 대해 알아보자

캐시라는 용어는 누구나 들어봤을 것입니다. 사실 캐시의 의미는 매우 광범위합니다. 컴퓨터에서 가장 큰 캐시는 메모리 스틱으로 구현할 수 있고 그래픽 카드의 비디오 메모리는 그래픽 칩에

itgall.com

 

https://mangkyu.tistory.com/69

 

[Server] Cache(캐시)란?

1. 캐시(Cache)란? [ Cache ] Cache란 자주 사용하는 데이터나 값을 미리 복사해 놓는 임시 장소를 가리킨다. 아래와 같은 저장공간 계층 구조에서 확인할 수 있듯이, 캐시는 저장 공간이 작고 비용이

mangkyu.tistory.com

https://nesoy.github.io/articles/2018-06/Java-volatile

 

Java volatile이란?

 

nesoy.github.io

https://blog.naver.com/PostView.nhn?blogId=cjsksk3113&logNo=222282586535 

 

캐시 메모리의 쓰기 정책 : Write-Through, Write-Back

캐시 메모리는 CPU 프로세서의 동작을 돕기 위한 임시 메모리 저장소이다. 따라서 CPU 프로세서가 캐...

blog.naver.com

 

반응형

'CS > 컴퓨터구조' 카테고리의 다른 글

[컴퓨터구조] 하버드 구조와 폰 노이만 구조  (0) 2022.01.26
반응형

3-way handshake와 4-way handshake는 TCP 프로토콜에서 연결을 시작/종료할때 쓰는 방식이다.

우선 TCP부터 알아보자.

 

TCP

TCP란 연결 지향적 프로토콜로 데이터패킷을 주고받을때 신뢰성을 보장한다.

 

그외 특징으로는

  • 흐름 제어, 혼잡 제어, 오류 제어
  • UDP보다 느린 대신 OSI 4계층(transport)에서 신뢰성 보장
  • 파일을 분할해서 전송(MSS)
  • 연결형 서비스로 가상 회선 방식을 제공

신뢰성을 보장하는 방식으로는 패킷을 보낸 후, 수신 확인(ACK)를 받는다.

제한시간내에 ACK가 오지 않는다면 패킷이 네트워크 중간에 손실되었다고 가정하고 다시 보낸다.

따라서 해당 방식때문에 신뢰성을 보장하지만 느리다.

(혼잡제어나 패킷을 보내는 방식은  흥미로운 부분이라 나중 글을 관련 부분으로 더 쓸 예정)

 

3-way handshake

연결하기 위해 두 장치의 논리적 접속을 성립하기 위해 사용하는 연결 확인 방식이다.

3번의 확인을 거친다고 해서 3 way handshake라 부른다

 

tmi) 4계층(transport)는 host 프로세스와 guest 프로세스 간 양 호스트 종단의 논리적 통신을 보장하고,

3계층(network)는 host와 guest 간 논리적 통신을 보장한다.

 

 

접속 시도시 client는 SYN 패킷을 보내 server에 접속 요청을 보낸다.

서버는 SYN 패킷을 받으면 접속이 가능하다는 의미로 client에세 SYN과 ACK 패킷을 보낸다.

client는 서버에세 SYN+ACK 패킷을 받았다면 이제 통신을 시작했다는 의미로 ACK를 보내고,

통신을 시작한다.

 

SYN (synchronize sequence numbers) - 연결 확인을 위해 보내는 무작위의 숫자값

ACK (acknowledgements) - Client 혹은 Server로부터 받은 SYN에 1을 더해 SYN을 잘 받았다는 ACK

ISN (Initial sequence numbers) - Client와 Server가 각각 처음으로 생성한 SYN

 

- SYN의 값에 무작위 수를 사용하는 이유?

  • Connection을 맺을 때 사용하는 포트는 유한 범위 내에서 사용하고 시간이 지남에 따라 재사용된다. 따라서 두 통신 호스트가 과거에 사용된 포트 번호 쌍을 사용할 가능성이 존재한다. 서버 측에서 패킷의 SYN을 보고 패킷을 구분하게 되는데 난수가 아닌 순차적인 숫자가 전송된다면 이전의 connection으로부터 오는 패킷으로 인식할 수 있어 이러한 문제 발생 가능성을 줄이기 위해 ISN을 무작위 난수로 사용하는 것이다.

 

4-way handshake

4-way handshake는 반대로 가상 회선 연결을 해제할때 주고 받는 확인 작업이다.

4번의 확인과정을 거친다고 하여 4 way handshake라고 부른다.

 

흔히 client가 close를 요청하고, server가 확인하고 닫는다고 알려져 있는데

서버도 close를 요청할 수 있다.

그래서 먼저 4-way handshake를 요청하는 쪽을 Active Closer, 받는 쪽을 Passive Closer라 한다.

 

과정을 요약하자면

 

Active closer가 먼저 서버를 닫고 싶다는 FIN 요청을 보내고 FIN-wait 상태에 들어간다.

그럼 Passive closer는 알았다는 ACK를 보내고, close-wait 상태에 들어간다.

그리고 Passive closer는 통신을 종료할 준비가 완료되면 FIN 을 다시 Active closer에 보낸다.

Active Closer는 FIN을 받았으면 time-wait 과정에 들어가고 ACK를 passive closer에게 보낸다. 

passive closer는 ACK를 받으면 통신을 종료한다.

active closer는 time wait상태에서 대기하다가 통신을 종료한다.

 

 

time wait는 

 

먼저 연결을 끊는 (active closer) 쪽에 생성되는 소켓으로, 혹시 모를 패킷 전송 실패에 대비하기 위하여 존재하는 소켓이다.

time-wait가 없다면 패킷의 손실이 발생하거나 통신자 간 연결 해제가 제대로 이루어지지 않을 수 있다.

 

 

읽어보면 좋을 글)

 

3 way handshake의 과정을 악용한 SYN flooding attack(보안)

https://run-it.tistory.com/51

 

SYN Flooding이란?

안녕하세요 여러분! IT 세계에는 다양한 분야가 존재합니다. 멀고 먼 험난한 길이지만... 우리는 지금까지 네트워크 영역을 다루고 이제 보안 영역에 들어와 계속해서 순항중에 있습니다. 비록

run-it.tistory.com

 

reference

 

https://seongonion.tistory.com/74

 

[네트워크] TCP 3-way & 4-way handshake란?

TCP란 연결 지향형 프로토콜로, 연속성 있는 데이터 패킷을 주고 받을 때 사용한다. TCP 특징 전송되는 데이터의 신뢰성 보장 (흐름 제어, 혼잡 제어, 오류 제어) 파일전송에 주로 사용 가상 회선을

seongonion.tistory.com

 

https://tech.kakao.com/2016/04/21/closewait-timewait/

 

CLOSE_WAIT & TIME_WAIT 최종 분석

트래픽이 많은 웹 서비스를 운영하다보면 CPU는 여유가 있지만 웹서버가 응답을 제대로 처리하지 못하고 먹통이 되는 경우를 종종 보게 됩니다. 여러가지 이유가 있겠지만, 이 글에서는 가장 대

tech.kakao.com

 

 

반응형

'CS > 네트워크' 카테고리의 다른 글

네트워크 관련 정리  (0) 2025.09.29
AnyCast란?  (0) 2022.04.11
URL & URI & URN  (0) 2022.02.27
HTTP 메소드 멱등성, 안전한 메소드  (0) 2022.01.31
Pooling, Long Pooling, Streaming  (0) 2022.01.23

+ Recent posts