
상황:
문제:

상황:
문제:
자원을 소유한 상태에서 추가 자원을 얻기 위해 기다림.
상대방도 동일한 방식으로 기다림.
결과적으로 무한 대기가 발생하여 시스템 정체.
📌식사하는 철학자 문제 (Dining Philosophers Problem)

설정:
규칙:
교착상태(Deadlock):
기아(Starvation):
활성화 지연(Livelock):
철학자가 식사하는 모든 경우 분석

📌철학자들의 교착상태 원인과 해결
환형 요청/대기(Circular Wait):
각 철학자가 특정 자원을 점유한 상태에서 다음 자원을 요청하며 대기.
모든 철학자가 동시에 동일한 상황에 처하면 환형 구조가 형성.
특징: 환형 대기는 스스로 인식하거나 해체할 수 없음.
‘환형 대기’가 발생하지 않도록 설계:
방법:
규칙적인 자원 요청 순서 설정:
포크 사용 우선순위 부여:

환형 요청 발생: 각 철학자가 왼쪽 포크를 소유하고 오른쪽 포크를 요청.
포크 충돌: 요청이 충돌하여 교착상태가 발생할 위험.
특정 철학자 우선 배정:
순환 요청 방지 규칙:
📌식사하는 철학자와 컴퓨팅 시스템
철학자 → 스레드
포크 → 자원
스파게티 → 스레드가 처리할 작업

T1~T5 스레드와 자원
컴퓨터 시스템에서 자원(파일, 프린터, 세마포, 뮤텍스 등)은 여러 스레드가 공유.
스레드가 특정 자원을 점유한 상태에서 다른 자원을 요청하며 무한 대기가 발생하는 것이 문제.
📌컴퓨터 시스템에서의 교착 상태 정의
정의:
발생 조건:
멀티스레드 응용프로그램:
운영체제 커널 내:
일상적인 발생 가능성:
시간과 공간 낭비:
대응 전략:
📌전형적인 멀티스레드 교착 상태 사례
스레드 간 자원 경쟁:
thread1, thread2)가 서로 다른 락(Lock)을 점유하고, 동시에 상대가 점유한 락을 요청하며 대기.다중 CPU 환경에서도 발생:

thread1:
LockA를 점유 후, LockB를 요청하고 대기.thread2:
LockB를 점유 후, LockA를 요청하고 대기.결과:
pthread_mutex_lock(): void* thread1(void* a) {
pthread_mutex_lock(&LockA); // LockA 획득
pthread_mutex_lock(&LockB); // LockB 요청 → 대기 발생 가능 (교착 발생 가능)
pthread_mutex_unlock(&LockB);
pthread_mutex_unlock(&LockA);
}
void* thread2(void* a) {
pthread_mutex_lock(&LockB); // LockB 획득
pthread_mutex_lock(&LockA); // LockA 요청 → 대기 발생 가능 (교착 발생 가능)
pthread_mutex_unlock(&LockA);
pthread_mutex_unlock(&LockB);
}
📌컴퓨터 시스템에 잠재된 교착 상태 유발 요인
컴퓨터 시스템에는 다양한 자원 존재:
뮤텍스, 스핀락, 세마포, 파일, 이터베이스, 파일 락 등.프린터, 메모리, 프로세서 등.다수의 스레드 또는 프로세스가 동일 자원에 접근하려 할 때 충돌 발생 가능.
스레드 간의 자원 경쟁:
자원 할당 정책:
비선점 정책:
📌교착 상태 모델링
그래프의 요소
시스템 내 자원의 상태를 나타내는 방향성 그래프
교착 상태를 예방, 회피, 감지하기 위한 기본 도구.
알고리즘 개발에 사용:
📌자원 할당 그래프 사례

📌교착상태가 발생하지 않은 자원할당 그래프와 교착상태가 발생한 사례
1. 교착상태가 아닌 경우

환형 사이클 형성:
진정한 교착상태가 아닌 이유:
T5가 실행을 종료하면, T5가 소유하고 있던 파일 자원이 해제됨.
이 파일 자원은 T4가 요청했던 자원이므로 T4가 이를 소유할 수 있음.
교착 상태 해소 과정:
T5와 T4가 각각 실행을 종료하고 자원을 반환하면서, T1, T2, T3 사이의 환형 사이클이 자연스럽게 풀리게 되어 시스템은 영구적인 교착 상태로 가지 않게 됨.
2. 교착상태가 발생한 사례

📌교착상태에 빠진 응용프로그램 사례

deadlock.c 코드에서 다음 상황이 발생함:
worker1 스레드가 lock1을 획득한 후 2초 동안 멈춤. 이후 lock2를 요청하지만 대기 상태에 빠짐.
worker2 스레드는 반대로 lock2를 먼저 획득한 후 2초 동안 멈춤. 이후 lock1을 요청하며 대기 상태에 빠짐.
이 결과로 두 스레드가 각각 서로가 보유하고 있는 락을 요청하며 무한 대기 상태에 빠져 교착 상태가 발생한다.
코드를 컴파일하고 실행하면 lock1, lock2를 각각 점유하는 로그가 출력된 후 프로그램이 멈춘다. 이는 교착 상태에 빠졌음을 의미한다.

worker1과 worker2가 각각 lock1과 lock2를 점유하고, 서로 상대의 락을 요청하면서 교착 상태가 발생한다.
아래 방향성 그래프는 교착 상태의 원형 대기를 시각적으로 나타냄:
📌교착상태가 발생하는 4가지 필요충분 조건
코프만 조건(Coffman condition)
상호 배제(Mutual Exclusion)
소유하면서 대기(Hold & Wait)
강제 자원 반환 불가(No Preemption)
환형 대기(Circular Wait)
✅ 4가지 조건 중 하나라도 성립되지 않으면, 교착상태 발생하지 않음
📌교착상태 해결 방법:
교착상태 예방 (Prevention)
교착상태 회피 (Avoidance)
교착상태 감지 및 복구 (Detection and Recovery)
교착상태 무시 (Ignore)
📌교착상태 예방 (Deadlock Prevention):
코프만의 4가지 조건 중 최소 하나를 성립하지 못하게 하여 교착상태를 방지한다.
조건: 동시에 2개 이상의 스레드가 자원을 공유할 수 없음.
해결 방법: 상호 배제 없애기.
조건: 자원을 소유한 스레드가 다른 자원을 요청하며 기다림.
해결 방법: 스레드가 자원을 기다리지 않도록 설계.
조건: 할당된 자원을 강제로 회수할 수 없음.
해결 방법: 자원 선점 허용.
조건: 자원을 기다리는 스레드들이 서로 원형으로 연결되어 무한 대기.
해결 방법: 자원 요청 순서를 정의하여 환형 대기 방지.
📌환형 대기가 발생하지 않도록 번호 순으로 자원 할당

📌교착상태 회피
자원 할당 시, 미래에 환형 대기가 발생할 가능성이 있다고 판단되면 자원 할당을 하지 않음.
교착상태 회피의 대표적인 방법으로 Banker’s Algorithm 사용.
안전한 상태:
불안전한 상태:
자원 요청 과정:
각 프로세스는 실행 시작 전에 필요한 자원의 총량을 운영체제에 알림.
자원을 요청할 때마다 시스템이 해당 요청을 처리해도 안전한 상태를 유지하는지 확인.
안전한 상태일 경우에만 자원 할당.
검증 과정:
시스템은 현재 자원 상태와 요청 상황을 시뮬레이션하여 모든 프로세스가 실행을 완료할 수 있는지 판단.
안전한 순서가 존재하면 자원 할당, 그렇지 않으면 요청 거절.
자원 수의 사전 정의:
오버헤드:
적용 어려움:
자원 강제 선점 (Preemption)
교착상태에 빠진 스레드 중 하나가 보유한 자원을 강제로 빼앗아 다른 스레드에게 할당한다.
선점된 스레드는 다시 자원을 요청해야 하므로 시스템의 상태가 변화한다.
롤백 (Rollback)
교착상태가 발생할 가능성이 있는 경우, 각 스레드의 상태를 주기적으로 저장한다.
교착상태가 감지되면 스레드를 이전 상태로 복원하여 교착상태를 해소한다.
하지만 롤백은 시간과 메모리 공간에 대한 비용이 크므로 잘 사용되지 않는다.
스레드 강제 종료 (Kill Process)
교착상태에 빠진 스레드 중 하나를 선택하여 강제로 종료시킨다.
가장 간단하면서도 효과적인 방법이다.
그러나 종료된 스레드가 처리하던 작업이 손실될 수 있으므로, 신중히 사용해야 한다.
교착상태에 대한 통계:
교착상태의 특성:
개념:
사용 환경:
타조 알고리즘이 적합하지 않은 경우:
핵 시스템, 비행기, 미사일 시스템 등 하드 리얼타임(hard real-time) 시스템에서는 치명적인 결과를 초래할 수 있다.
예를 들어, 이러한 시스템에서는 시스템 재시작이나 작업 중단이 치명적인 결과를 가져올 수 있으므로, 교착상태 감지 및 회피가 필수적이다.