이제 교착상태에서 회복하는 방식을 생각해보자.
1. 프로세스/쓰레드 끄기
- 흔히 abort라고 터미널 창에 뜨는 그것이다.
- 두 가지 방법이 있으며, 이들 모두 종료된 프로세스에 할당되는 자원을 모두 회수한다.
- 교착 상태 프로세스를 모두 중지
- 확실하게 교착 상태의 사이클을 깨지만, 비용이 굉장히 크다.
- 프로세스가 오랫동안 연산한 결과를 버리고, 다시 재연산해야 하기 때문이다.
- 교착 상태가 제거될 때까지 하나씩 중지
-
프로세스 1개 종료 ⇒ 교착 상태 탐지 를 반복한다.
-
상당한 오버헤드를 유발한다.
-
어떤 프로세스를 종료시킬지 결정해야 한다.
결정하는 과정에서 피해를 최소화하는 것이 필요하며, 그 기준은 크게 다음과 같다.
- 프로세스의 우선순위
- 프로세스 수행 시간과 종료 시간
- 프로세스가 사용한 자원 유형과 수
- 프로세스가 종료하기 위해 필요한 자원 수
- 프로세스가 몇 개나 종료되어야 하는지
-
프로세스를 중지시키는 것은 쉬운 일이 아니다.
파일을 갱신시키는 프로세스면, 중단 시 그 파일이 엉망이 된다.
뮤택스 락을 점유한 상태에서 공유 데이터를 갱신하는 중이면, 그 공유데이터의 무결성은 보장할 수 없다.
(물론, 운영체제가 알아서 공유 데이터를 복구시켜야 한다.)
2. 자원 선점하기
교착상태가 깨어질 때까지 멈춘 프로세스로부터 계속 자원을 선점해 다른 프로세스에게 자원을 주는 방식.
다음의 3가지 사항을 고려해서 설계할 필요가 있다.
-
희생자 선택 : 어떤 프로세스의 무슨 자원이 선점될 것인가?
피해를 최소화해야 하기 때문에, 선점의 순서를 결정할 필요가 있다.
그 기준은 위의 프로세스/쓰레드 끄기의 기준과 비슷하다.
-
후퇴 : 프로세스에게서 자원을 선점하려면, 프로세스를 어떻게 해야 하는가?
프로세스를 교착상태를 깨트릴 정도로만 후퇴시키는 것이 목표가 되어야 한다.
즉, 프로세스에 대한 더 많은 정보가 필요하다.
-
기아상태와 왕따 : 선점하다가 기아 상태가 발생하지는 않을까?
자원들이 특정 프로세스에게만 가는건 아닌지 보장할 방법이 필요하다.
동일한 프로세스가 항상 희생자로(=왕따) 선정되는 건 아닌지도 고려해 줘야 한다.
프로세스는 희생자로 짧은 시간동안만 선정된다는 점 역시 고려사항.
완벽한 해결책은 존재하지 않지만, 3가지를 고려할 필요가 있다.
일반적인 해결법은 비용 요소에 후퇴의 횟수를 포함시키는 것.