프로세스를 실행하기 위해서는 CPU, 메모리, I/O 장치와 같은 다양한 자원이 필요하다. 두 개 이상의 프로세스가 각각 자원을 보유한 채 서로가 가진 자원을 무한히 기다리기만 한다면, 어떤 프로세스도 더 이상 진행할 수 없는 상태에 빠지게 되는데 이를 교착 상태(Deadlock) 라고 한다.
대표적인 예시가 바로 식사하는 철학자 문제이다. 여러 철학자가 원형 테이블에 앉아 식사를 하며, 식사를 하기 위해서는 양옆에 놓인 두 개의 포크가 모두 필요하다. 모든 철학자가 동시에 왼쪽 포크만 집고 오른쪽 포크를 기다린다면, 누구도 식사를 시작하지 못한 채 영원히 대기하게 된다. 이 문제는 자원을 점유한 채 다른 자원을 기다릴 때 교착 상태가 어떻게 발생하는지를 직관적으로 보여준다.
교착 상태란 결국 일어나지 않을 사건(자원 반환)을 기다리며 시스템의 진행이 완전히 멈춰버리는 현상이다. 이는 뮤텍스 락(Mutex Lock) 환경에서도 발생할 수 있다. 예를 들어 프로세스 A와 B가 각각 서로 다른 문을 잠근 상태에서, 상대방이 잠근 문이 열리기만을 기다린다면 두 프로세스 모두 영원히 대기하게 되어 교착 상태에 빠진다.
교착 상태는 자원 할당 그래프(Resource Allocation Graph) 를 통해 시각적으로 표현할 수 있다. 이 그래프에서는
이를 통해 어떤 프로세스가 어떤 자원을 보유하고 있으며, 또 어떤 자원을 기다리고 있는지를 한눈에 파악할 수 있다.
교착 상태가 발생하기 위해서는 다음 네 가지 조건이 모두 동시에 만족되어야 한다. 이 중 하나라도 성립하지 않으면 교착 상태는 발생하지 않는다.
상호 배제(Mutual Exclusion)
자원은 한 번에 하나의 프로세스만 사용할 수 있다. 이미 사용 중인 자원은 다른 프로세스가 동시에 사용할 수 없으며, 이러한 상호 배제 조건이 존재할 때 교착 상태의 가능성이 생긴다.
점유와 대기(Hold and Wait)
프로세스가 하나 이상의 자원을 이미 점유한 상태에서, 추가적인 자원을 얻기 위해 대기하는 상황이다. 식사하는 철학자 문제에서 철학자가 포크 하나를 들고 다른 포크를 기다리는 경우가 이에 해당한다.
비선점(No Preemption)
한 프로세스가 점유한 자원을 다른 프로세스가 강제로 빼앗을 수 없다. 자원은 해당 프로세스가 자발적으로 반환할 때만 해제된다.
원형 대기(Circular Wait)
프로세스들이 자원 요청과 할당 관계에서 원형 구조를 이룬다. 예를 들어 A는 B의 자원을, B는 C의 자원을, C는 다시 A의 자원을 기다리는 형태이다. 단, 원형 구조가 존재한다고 해서 항상 교착 상태가 발생하는 것은 아니지만, 교착 상태의 필요 조건 중 하나이다.
교착 상태를 다루는 방법은 크게 예방, 회피, 검출 후 회복 세 가지로 나뉜다.
교착 상태의 네 가지 필요 조건 중 하나 이상을 원천적으로 만족하지 못하게 만드는 방법이다.
상호 배제 제거
현실적으로 모든 자원에 대해 상호 배제를 제거하는 것은 어렵다. 다만 GPU 영역에서는 MPS(Multi-Process Service)나 MIG(Multi-Instance GPU)처럼 하나의 물리 GPU를 논리적으로 분할하여 여러 프로세스가 동시에 사용하는 방식이 상호 배제의 영향을 완화하는 사례로 볼 수 있다.
점유와 대기 제거
프로세스가 자원을 요청할 때 필요한 모든 자원을 한 번에 요청하여, 모두 할당될 때만 실행을 허용하는 방식이다. 식사하는 철학자 문제에서는 두 개의 포크를 동시에 들 수 있을 때만 식사를 허용하는 경우가 이에 해당한다. 교착 상태는 방지할 수 있지만, 자원 활용률이 낮아질 수 있다.
비선점 조건 제거
일부 자원에 대해서는 선점이 가능하다. 예를 들어 CPU는 선점이 가능하지만, 프린터처럼 작업 도중 중단이 어려운 자원은 비선점적이다. 선점 가능한 자원에 대해서만 효과적으로 적용할 수 있다.
원형 대기 제거
모든 자원에 번호를 부여하고, 프로세스는 항상 오름차순으로만 자원을 요청하도록 제한한다. 이렇게 하면 원형 대기가 발생하지 않는다. 다만 실제 시스템에서 모든 자원에 일관된 순서를 부여하는 것은 쉽지 않다.
이러한 예방 기법은 교착 상태가 발생하지 않음을 보장하지만, 성능 저하나 자원 활용률 감소 같은 부작용이 존재한다.
교착 상태 회피는 자원을 조심스럽게 할당하는 방식이다. 시스템이 항상 교착 상태에 빠지지 않는지를 검사하면서 자원을 할당한다.
대표적인 알고리즘으로는 은행원 알고리즘(Banker’s Algorithm)이 있다.
교착 상태의 발생을 허용하되, 사후에 이를 검출하고 해결하는 방식이다.
이 외에도 실제 많은 운영체제에서는 교착 상태를 무시하는 타조 알고리즘(Ostrich Algorithm) 을 사용하기도 한다. 교착 상태 발생 빈도가 매우 낮고, 처리 비용이 크기 때문에 현실적인 선택이 되는 경우도 있다.
MIG란 무엇인가?
https://toss.tech/article/toss-securities-gpu-mig
MIG(Multi-Instance GPU) 는 “상호 배제는 정말 피할 수 없는가?”라는 질문에 대해 현실적인 반례에 가까운 기술
MIG (Multi-Instance GPU) 는
하나의 물리적 GPU를 여러 개의 독립적인 논리 GPU 인스턴스로 분할하는 NVIDIA 기술이다.
즉, 하나의 GPU를 여러 프로세스가 동시에, 안전하게, 분리된 상태로 사용할 수 있다.
GPU는 기본적으로 상호 배제적 자원
한 프로세스가 GPU를 점유하면:
MPS는 여러 프로세스를 동시에 실행하긴 하지만:
→ 논리적 공유일 뿐, 자원 자체는 여전히 섞여 있음
MIG는 GPU를 하드웨어 수준에서 분할한다.
각 MIG 인스턴스는 다음을 전용으로 할당받는다.
즉,
MIG 인스턴스 = 거의 하나의 물리 GPU처럼 동작
다른 인스턴스와:
기존:
GPU (단일 자원)
└── 여러 프로세스가 경쟁
MIG 적용 후:
GPU
├── MIG-0 (GPU0)
├── MIG-1 (GPU1)
├── MIG-2 (GPU2)
운영체제 입장에서는:
/dev/nvidia0, /dev/nvidia1처럼 분리교착 상태 조건 중 하나인 상호 배제(Mutual Exclusion) 는
“한 자원을 동시에 하나의 프로세스만 사용할 수 있는가?”이다.
즉,
상호 배제를 없앤 것은 아니지만
상호 배제가 걸리는 자원의 크기를 줄인 것
이 점이 매우 중요하다.
기존 GPU:
MIG:
👉 교착 상태 발생 확률 자체를 구조적으로 낮춤
정확히 말하면 MIG는:
따라서 교착 상태 해결 분류로 보면:
예방 기법의 실용적 확장 사례
라고 설명하는 게 가장 정확하다.
MIG는 하드웨어 종속 기술
전통 OS 이론은 추상 자원 모델을 다룸
하지만 현대 시스템에서는:
👉 현대 운영체제/시스템 설계에서는 매우 중요한 사례
MIG는 GPU를 하드웨어 수준에서 여러 개의 독립된 인스턴스로 분할함으로써,
전통적으로 상호 배제적이던 GPU 자원의 경쟁을 완화하고
교착 상태 발생 가능성을 구조적으로 낮추는 실용적인 자원 관리 기법이다.