운영체제 — 3강: 프로세스 동기화·교착상태·파일 시스템
프로세스 동기화: 임계 구역 문제
경쟁 조건 (Race Condition):
→ 여러 프로세스/스레드가 공유 자원에 동시 접근
→ 실행 순서에 따라 결과가 달라지는 상황
→ 예: count++ (읽기→증가→쓰기) 원자적 아님
임계 구역 (Critical Section):
→ 공유 자원을 접근하는 코드 영역
→ 동시에 하나의 프로세스만 실행 가능
임계 구역 해결 조건:
① 상호 배제 (Mutual Exclusion):
한 번에 하나의 프로세스만 임계 구역 진입
② 진행 (Progress):
임계 구역에 없는 프로세스가 다른 프로세스를 막으면 안 됨
③ 한정 대기 (Bounded Waiting):
무한 대기 방지 — 유한 번 기다리면 반드시 진입 가능
피터슨 알고리즘:
→ 소프트웨어 기반 2-프로세스 해결책
→ turn + flag 변수 사용
→ 현대 CPU 최적화(재배열)로 동작 보장 어려움
동기화 도구
뮤텍스 (Mutex Lock):
→ 이진 잠금 (잠김/열림)
→ acquire() → 임계 구역 → release()
→ Busy Waiting (스핀락): CPU 낭비 — 짧은 임계 구역에 적합
→ Sleep & Wake: 긴 임계 구역에 적합
세마포어 (Semaphore, Dijkstra):
→ 정수 변수 S
→ wait(P): S-- (S < 0이면 블록)
→ signal(V): S++ (블록된 프로세스 깨움)
→ 이진 세마포어: Mutex와 동일
→ 계수 세마포어: 자원 수 제한 (N개 접근 허용)
모니터 (Monitor):
→ 고수준 동기화 추상화
→ 뮤텍스 + 조건 변수(Condition Variable) 통합
→ Java synchronized: 모니터 방식
→ wait(): 모니터 잠금 해제 후 대기
→ notify() / notifyAll(): 대기 중인 스레드 깨움
조건 변수 (Condition Variable):
→ pthread_cond_wait, pthread_cond_signal
→ 특정 조건을 기다릴 때 사용
→ 반드시 뮤텍스와 함께 사용
원자적 연산 (Atomic Operations):
→ 하드웨어 지원: TestAndSet, CompareAndSwap
→ 분리 불가능한 단일 연산
→ 락-프리(Lock-Free) 자료구조의 기반
고전 동기화 문제
생산자-소비자 문제 (Bounded Buffer):
→ 생산자: 버퍼가 가득 차면 대기
→ 소비자: 버퍼가 비면 대기
→ 세마포어 해결:
mutex = 1 (상호 배제)
empty = N (빈 슬롯 수)
full = 0 (찬 슬롯 수)
독자-작가 문제 (Readers-Writers):
→ 여러 독자 동시 읽기 허용
→ 작가는 독점 접근
→ 1종 해결: 독자 우선 → 작가 기아 가능
→ 2종 해결: 작가 우선 → 독자 기아 가능
식사하는 철학자 문제 (Dining Philosophers):
→ 5명의 철학자, 5개의 젓가락
→ 양쪽 젓가락 모두 있어야 식사
→ 교착상태 위험: 모두 왼쪽 잡고 오른쪽 기다림
→ 해결책:
① 최대 4명만 테이블에
② 양쪽 동시 집거나 안 집음 (원자적)
③ 비대칭: 홀수 왼쪽·짝수 오른쪽 먼저
④ 모니터 활용
스레드 안전성 (Thread Safety):
→ 여러 스레드에서 동시 사용해도 올바르게 동작
→ 불변 객체, TLS(Thread Local Storage), 동기화
교착상태 (Deadlock)
교착상태 발생 4가지 조건 (Coffman):
→ 모두 성립해야 교착상태 발생
① 상호 배제 (Mutual Exclusion):
한 번에 하나의 프로세스만 자원 사용
② 점유와 대기 (Hold and Wait):
자원 보유 중 추가 자원 대기
③ 비선점 (No Preemption):
자원을 강제로 빼앗을 수 없음
④ 순환 대기 (Circular Wait):
P1→P2→P3→P1 순환 형태
교착상태 처리 방법:
예방 (Prevention):
→ 4가지 조건 중 하나 제거
→ 점유와 대기 제거: 모든 자원 한번에 요청
→ 비선점 제거: 자원 강제 회수
→ 순환 대기 제거: 자원 순서 지정
회피 (Avoidance):
→ 은행원 알고리즘 (Banker's Algorithm)
→ 안전 상태(Safe State) 유지
→ 안전 순서열이 존재: 교착상태 없이 완료 가능
→ 할당 전에 안전 상태 확인 후 결정
탐지 (Detection):
→ 자원 할당 그래프 사용
→ 그래프에 사이클이 있으면 교착상태
→ 대기 그래프(Wait-For Graph)
회복 (Recovery):
→ 프로세스 종료: 교착상태 프로세스 강제 종료
→ 자원 선점: 자원 강제 회수 후 재할당
→ 되돌리기(Rollback): 체크포인트로 복구
현실적 접근:
→ 대부분의 OS: 교착상태 무시 (타조 알고리즘)
→ 개발자 책임: 교착상태 없도록 프로그래밍
파일 시스템
파일 시스템 개요:
→ 저장 장치에 파일 구성·관리
→ 이름, 접근 방법, 보호 제공
→ 디렉터리: 파일 이름 → 파일 메타데이터 매핑
파일 접근 방법:
→ 순차 접근: 순서대로 읽기 (테이프)
→ 직접 접근: 임의 블록 접근 (디스크)
→ 인덱스 방식: 인덱스 블록 → 데이터 블록
디스크 할당 방법:
연속 할당:
→ 연속된 블록에 저장
→ 빠른 접근, 외부 단편화 문제
연결 할당 (Linked):
→ 각 블록이 다음 블록 포인터 보유
→ FAT(File Allocation Table): 포인터를 별도 테이블에
→ 직접 접근 느림
인덱스 할당:
→ 인덱스 블록에 데이터 블록 번호 저장
→ 직접 접근 효율적
→ 작은 파일은 인덱스 블록 낭비
inode (Unix/Linux):
→ 파일 메타데이터 + 블록 포인터 저장
→ 직접 포인터 12개 (작은 파일)
→ 단일 간접, 이중 간접, 삼중 간접
→ 파일 이름은 디렉터리에 저장 (inode 번호 매핑)
파일 시스템 유형:
→ FAT32: 구형, 4GB 이하 파일, USB
→ NTFS: Windows, 저널링, ACL 지원
→ ext4: Linux 표준, 저널링
→ APFS: Apple, SSD 최적화, 스냅샷
→ ZFS/Btrfs: 스냅샷, 자동 복구
저널링:
→ 변경 전 로그 기록 → 장애 시 복구
→ Write-Ahead Log (WAL)
→ 메타데이터만 저널링(더 빠름) vs 데이터도 저널링
자주 묻는 질문
Q. 뮤텍스와 세마포어의 차이는 무엇인가요? A. 뮤텍스는 잠금을 획득한 스레드만 해제할 수 있는 소유권 개념이 있습니다. 반면 세마포어는 소유권이 없어 한 스레드가 wait를 호출하고 다른 스레드가 signal을 호출할 수 있습니다. 이 차이 때문에 뮤텍스는 임계 구역 보호에, 세마포어는 자원 카운팅이나 이벤트 알림(생산자-소비자)에 더 적합합니다. 또한 뮤텍스는 보통 이진(0/1)이지만 세마포어는 N개 자원 동시 허용에 사용할 수 있습니다.
Q. 은행원 알고리즘이 실제 OS에서 잘 쓰이지 않는 이유는 무엇인가요? A. 세 가지 현실적 한계가 있습니다. 첫째, 프로세스의 최대 자원 요구량(max)을 미리 알아야 하는데 실제로는 알 수 없는 경우가 많습니다. 둘째, 자원 유형과 프로세스 수가 고정되어야 하지만 실제 시스템에서는 동적으로 변합니다. 셋째, 할당 전마다 안전 상태 계산이 필요해 오버헤드가 큽니다. 따라서 대부분 OS는 교착상태를 그냥 무시하거나 탐지 후 복구하는 방식을 택합니다.
O
OIYO 편집부
Content Editor지식 인큐베이터이자 전문 콘텐츠 크리에이터. 경영, 경제, 법률 및 실생활에 유용한 실무/자격증 중심의 깊이 있는 정보를 연구하고 공유합니다.