멀티쓰레드 환경에서 발생할 수 있는 문제들
멀티쓰레드는 하나의 프로세스 내에서 여러 작업을 동시에 처리할 수 있어, CPU 자원을 효율적으로 활용할 수 있게 해준다.
하지만 동시에 여러 쓰레드가 동일한 자원에 접근하게 되면 다양한 문제가 발생할 수 있으며, 이들 문제는 시스템 안정성과 성능에 직접적인 영향을 미친다.
1. 경쟁 조건 (Race Condition)
정의
여러 쓰레드가 동시에 같은 자원(예: 전역 변수, 파일 등)에 접근하고 수정하려 할 때 발생하는 문제로,
실행 순서에 따라 결과가 달라지는 비결정적 현상이다.
예시
cpp
복사편집
counter++; // 읽기 → 증가 → 쓰기 (세 단계 중간에 다른 쓰레드가 개입 가능)
문제점
- 간헐적이고 재현이 어려운 버그 발생
- 결과값이 불안정하거나 예측 불가능
해결
- 뮤텍스, 세마포어, atomic 변수 등 동기화 도구 사용
더 자세한 설명 : 경쟁 조건
2. 데드락 (Deadlock)
정의
두 개 이상의 쓰레드가 서로가 가진 자원을 기다리며 무한히 대기하는 상태
발생 조건 (4가지 모두 충족 시)
- 상호 배제
- 점유 대기
- 비선점
- 순환 대기
해결 방법
- 자원 요청 순서 고정
- 타임아웃 설정
- 예방, 회피 기법 (예: Banker’s Algorithm)
더 자세한 설명 : 데드락
3. 라이브락 (Livelock)
정의
데드락처럼 쓰레드들이 작업을 완료하지 못하는 상태지만,
서로 양보하며 계속 상태만 바뀌고 실제 진전은 없는 상태
특징
- 멈춘 것처럼 보이진 않음 (계속 동작함)
- 실제 결과는 없음
예시
- 두 스레드가 서로 양보하느라 무한 루프를 도는 경우
4. 기아 상태 (Starvation)
정의
어떤 스레드가 자원을 할당받지 못한 채 무한히 대기하는 상황
원인
- 우선순위 기반 스케줄링에서 낮은 우선순위의 스레드가 계속 밀림
- 락 경쟁에서 지속적으로 실패
해결 방법
- 에이징(Aging) 기법을 사용해 대기 시간이 길어지면 우선순위를 올림
5. 캐시 일관성 문제 (Cache Coherency)
정의
멀티코어 시스템에서 각 코어가 자체 캐시를 갖고 있을 경우,
한 스레드가 데이터를 수정해도 다른 코어의 스레드는 이전 캐시 값을 사용할 수 있는 문제
예시
- A 코어에서 수정한 데이터가 B 코어 캐시에 반영되지 않아 엉뚱한 값을 참조
해결 방법
- MESI 등의 캐시 일관성 프로토콜 사용
- volatile, atomic, memory barrier 등을 통해 CPU에게 캐시 동기화 명시
6. 동기화 오버헤드 (Synchronization Overhead)
정의
락, 뮤텍스, 세마포어 등 동기화 도구를 사용하면 데이터의 일관성을 확보할 수 있지만,
성능 저하나 락 경합(lock contention)이 발생할 수 있다.
문제점
- 과도한 락 사용 시 병목 발생
- 임계영역이 길어질수록 시스템 전체의 응답성이 떨어짐
해결 방법
- 임계영역 최소화
- 락을 쓰지 않는 lock-free 알고리즘 고려
- RW락, 세분화된 락 분리
7. 잘못된 공유 자원 관리
정의
공유 자원(메모리, 파일 등)을 할당한 후 해제하지 않거나 중복 접근으로 충돌이 발생하는 상황
문제점
- 자원 누수 발생
- 예기치 않은 동작, 시스템 불안정
- Double-free, use-after-free 같은 심각한 메모리 버그 가능
해결 방법
- 소유권 명확히 정의
- RAII, 스마트 포인터 등 자원 자동 관리 도입
- 접근 전 동기화 확인
'OS' 카테고리의 다른 글
세마포어(Semaphore) (0) | 2025.06.24 |
---|---|
뮤텍스(Mutex) (0) | 2025.06.24 |
다양한 OS 스케줄링 기법 (0) | 2025.06.24 |
쓰레드와 프로세스 (Thread & Process) (0) | 2025.06.24 |
경쟁 조건(Race Condition)이란? (0) | 2025.06.24 |