교착상태를 설명하는 가장 고전적인 문제 상황에 대한 예시가 아래에 있다.
동그란 원탁에 다섯 명의 철학자가 앉아 있다. 이 철학자들 앞에는 맛있는 식사가 있고, 철학자들 사이 사이에는 식사에 필요한 포크가 있다. 그리고 철학자들 앞에 있는 식사는 두 개의 포크로 먹을 수 있는 음식이라고 가정한다. 해당 철학자들은 아래와 같은 순서로 식사를 한다.
1. 계속 생각을 하다가 왼쪽 포크가 사용 가능하면 집어든다. 2. 계속 생각을 하다가 오른쪽 포크가 사용 가능하면 집어든다. 3. 왼쪽과 오른쪽 포크를 모두 집어들면 정해진 시간동안 식사를 한다. 4. 식사 시간이 끝나면 오른쪽 포크를 내려놓는다. 5. 오른쪽 포크를 내려놓은 뒤 왼쪽 포크를 내려놓는다. 6. 다시 처음부터 반복한다.
문제가 없어보이지만... 모든 철학자가 동시에 포크를 집어 식사를 하면 어떤 철학자도 식사를 할 수 없고 영원히 생각만 하는 상황이 발생할 수 있다.
→ 모든 철학자가 왼쪽 포크를 집어들면 모두가 오른쪽 포크를 집어들 수 없기 때문!
📍 일어나지 않은 사건을 기다리며 진행이 멈춰버리는 현상을 교착 상태라고 한다.
교착상태를 해결하기 위한 두 가지 방법
어떤 프로세스가 어떤 자원을 사용하고 있고, 또 어떤 프로세스가 어떤 자원을 기다리고 있는지를 표현하는 간단한 그래프
규칙
1. 프로세스는 원, 자원의 종류는 사각형으로 표현
2. 사용할 수 있는 자원의 개수는 자원 사각형 내에 점으로 표현
3. 프로세스가 어떤 자원을 할당받아 사용 중이라면 자원에서 프로세스를 향해 화살표를 표시
4. 프로세스가 어떤 자원을 기다리고 있다면 프로세스에서 자원으로 화살표를 표시
식사하는 철학자 문제를 자원 할당 그래프로 표현하면 다음과 같다.
교착 상태가 발생한 상황은 자원 할당 그래프가 원의 형태를 띄고 있다.
교착상태가 발생하는 근본적인 이유는 무엇일까? 교착 상태가 발생하는 조건은 네 가지가 있다. 이 조건이 모두 만족될 때 교착 상태가 발생할 가능성이 생긴다.
한 프로세스가 사용하는 자원을 다른 프로세스가 사용할 수 없을 때, 즉 상호 배제 상황에서 교착 상태가 발생할 수 있다.
교착 상태가 발생한 근본 원인은 해당 자원을 한 번에 하나의 프로세스만 이용 가능했기 때문이다.
어떠한 자원을 할당받은 상태에서 다른 자원을 할당받기를 기다린다면(=점유와 대기) 교착 상태가 발생할 수 있다.
자원을 보유한 채 다른 자원을 기다리기 때문에 문제가 발생한다.
어떤 프로세스도 다른 프로세스의 자원을 강제로 빼앗지 못했기 때문에 교착 상태가 발생한다.
이것을 프로세스가 자원을 비선점하고 있다고 말한다. 비선점 자원은 그 자원을 이용하는 프로세스의 작업이 끝나야만 비로소 이용이 가능하다.
프로세스들이 원의 형태로 자원을 대기하는 것을 원형 대기라고 한다.
프로세스들과 프로세스가 요청 및 할당받은 자원이 원의 형태를 이루면 교착 상태가 발생할 수 있다. 하지만 원의 형태를 띈다고 해서 반드시 교착 상태가 발생하는 것은 아니다.
교착 상태 발생 필요 조건 네 가지 중 하나를 충족하지 못하게 하는 방법!
이 말은 모든 자원을 공유 가능하게 만든다는 말이다.
☹️ 현실적으로 모든 자원의 상호 배제를 없애기는 어렵다.
점유와 대기를 없애면 운영체제는 특정 프로세스에 자원을 모두 할당하거나, 아예 할당하지 않는 방식으로 배분한다.
😀 이론적으로는 교착 상태를 해결할 수 있다.
☹️ 자원의 활용률이 낮아진다.
당장 자원이 필요해도 기다릴 수밖에 없는 프로세스와 사용되지 않으면서 오랫동안 할당되는 자원을 다수 양산하기 때문이다.
☹️ 많은 자원을 사용하는 프로세스가 불리해진다.
자원을 많이 사용하는 프로세스는 자원을 적게 사용하는 프로세스에 비해 동시에 자원을 사용할 타이밍을 확보하기가 어렵다. ➡️ 기아 현상 발생 위험
자원을 이용 중인 프로세스로부터 해당 자원을 빼앗을 수 있게 된다.
😀 선점하여 사용할 수 있는 일부 자원에 대해서는 효과적이다. (CPU)
☹️ 모든 자원이 선점 가능한 것은 아니다.
프린터같이 한 프로세스의 작업이 끝날 때까지 다른 프로세스가 기다려야 하는 자원도 얼마든지 있다. 그렇기 때문에 다소 범용성이 떨어지는 방안이다.
모든 자원에 번호를 붙이고, 오름차순으로 자원을 할당하는 방법이다.
식사하는 철학자 문제에서 포크에 번호를 붙이고, 철학자로 하여금 번호가 낮은 포크에서 높은 포크 순으로 집어들게 한다면 원형 대기는 발생하지 않는다.
😀 앞선 세 방식에 비하면 비교적 현실적이고 실용적인 방식
☹️ 하지만 모든 컴퓨터 시스템 내에 존재하는 수많은 자원에 번호를 붙이는 일은 그리 간단한 작업이 아닐 뿐더러 각 자원에 어떤 번호를 붙이는지에 따라 특정 자원의 활용률이 떨어질 수 있다
교착 상태의 발생 조건을 원천적으로 제거하여 교착 상태를 사전에 방지하는 예방 방식은 교착 상태가 발생하지 않음을 보장할 수는 있지만 여러 부작용이 따른다.
교착 상태가 발생하지 않을 정도로만 조심스럽게 자원을 할당하는 방식이다.
✔️ 교착 상태를 한정된 자원의 무분별한 할당으로 인해 발생하는 문제로 간주
식사하는 철학자 문제에서 만일 포크가 100개, 1000개 있는 상태였다고 생각해보자. 철학자들이 한두 개의 포크를 요구하면 교착 상태가 발생하지 않는다. 하지만 포크의 양이 충분하지 않은 상태에서 철학자들이 모두 최대의 포크(두 개)를 요구하면 교착 상태가 발생하는 것이다.
프로세스들이 배분할 수 있는 자원의 양을 고려하여 교착 상태가 발생하지 않을 정도의 양만큼만 자원을 배분하는 방법이 교착 상태 회피다.
교착 상태가 발생하지 않고 모든 프로세스가 정상적으로 자원을 할당받고 종료될 수 있는 상태
교착 상태가 발생할 수도 있는 상황
교착 상태 없이 안전하게 프로세스들에 자원을 할당할 수 있는 순서
➡️ 안전 순서열대로 프로세스들에 자원ㅇ르 배분하여 교착 상태가 발생하지 않는 상태를 안전 상태라고 한다
➡️ 안전 순서열이 없는 상황을 불안전 상태라고 한다
운영 체제가 교착 상태를 회피하기 위해서는 시스템 상태가 안전 상태에서 안전 상태로 움직이는 경우에만 자원을 할당하면 된다. 항시 안전 상태를 유지하도록 자원을 할당하는 방식과도 같다.
검출 후 회복 방식에서 운영체제는 프로세스들이 자원을 요구할 때마다 그때그때 모두 할당하며, 교착 상태 발생 여부를 주기적으로 검사한다. 교착 상태가 검출되면 다음과 같은 방식으로 회복한다.
✔️ 교착 상태 발생을 인정하고 사후에 조치하는 방식
교착 상태가 해결될 때까지 한 프로세스씩 자원을 몰아주는 방식
다른 프로세스로부터 자원을 강제로 빼앗고 한 프로세스에 할당하는 것이다.
운영체제는 교착 상태에 놓인 프로세스를 모두 강제 종료할 수도 있고, 교착 상태가 없어질 때까지 한 프로세스씩 강제 종료할 수 있다.
😀 가장 단순하면서 확실한 방식!
☹️ 첫 번째 방식에서는 그만큼 많은 프로세스들이 작업 내역을 잃게 될 가능성이 있다.
☹️ 두 번째 방식에서는 작업 내역을 잃는 프로세스는 최대한 줄일 수 있지만 교착 상태가 없어졌는지 여부를 확인하는 과정에서 오버헤드를 야기한다.
타조 알고리즘 - 드물게 발생하는 잠재적 문제를 무시로 대처하는 방식
완벽을 추구하는 입장에서는 뭐 이딴걸 방식이라고 하냐 할지 모르지만 문제의 발생 빈도나 심각성에 따라 최대 효율을 추구하는 엔지니어 입장에서는 때때로 이 방식이 적합할 때도 많다.