교착 상태가 발생하지 않도록 최소한 하나가 성립하지 않도록 보장한다. 이러한 기법을 예방이라고 한다. 문제점으로는 장치의 이용률이 낮아지고 시스템 총 처리율이 감소한다는것이다.
상호 배제를 하지 않음으로써 교착상태를 예방한다. 가장 좋은 예는 읽기-전용 파일이 공유 가능한 자원의 좋은 예이다. 여러 스레드가 읽기 전용의 파일을 열면, 그 파일에는 동시 접근을 허용한다. 다른 프로세스는 공유 가능한 자원을 위해 기다릴 필요가 없다. 하지만 이 방법으로는 근본적으로 해결할 수 없는데 이는 모든 자원이 공유 가능한 자원이 아니기 때문이다. 예를들어 mutex 락은 동시에 여러 스레드가 공유할 수 없다.
시스템에서 점유 대기 조건이 발생하지 않도록 하기 위해선 스레드가 자원을 요청할 때 다른 자원을 보유하지 않도록 해야한다.
위 두 방법의 해결도 문제를 가지고 있다. 첫째는 자원이 할당 되었지만 장기간 사용하지 않아 자원 이용률이 낮아지게 된다. 둘째는 기아가 발생할 수 있다. 인기 있는 여러 개의 자원이 필요한 스레드는 필요한 자원 중 적어도 하나는 항상 다른 스레드에 할당되므로 무한정 대기해야 할 수 있다.
우리는 비선점이 성립되지 않기 위해 자원을 선점 가능하도록 할 수 있다.
아래는 다른 방법을 설명하겠다.
일반적으로 해당 방법은 mutex락과 세마포같은 자원에는 적용될 수 없다. CPU레지스터나 데이터베이스 트랜잭션처럼 그 상태가 쉽게 저장되고 후에 복원될 수 있는 자원에 종종 적용된다.
위에 설명한 3가지 방법은 대부분 실용적이지 않은 방법이다. 순환대기 조건을 무효화 하면서 실용적인 해결책을 제공할 수 있다.
첫번째 방법으로는 모든 자원 유형에 전체적인 순서를 부여하여, 각 프로세스가 열거된 순서대로 오름차순으로 자원을 요청하도록 요구하는 것이다.
// 내용 추가
하지만 순서나 계층 구조를 정하는것 그 자체만으로는 교착상태를 예방할 수 없다. 예를 들어 송금 기능을 하는 함수가 있다고 가정하자.
void transaction(Account from, Account to, double amount){
mutex lock1, lock2;
lock1 = get_lock(from);
lock2 = get_lock(to);
acquire(lock1);
acquire(lock2);
withdraw(from, amount);
deposit(to, amount);
release(lock2);
release(lock1);
}
만약 transaction(checking_account, savings_account, 25.0)
와 transaction(savings_account, checking_account, 25.0)
이 동시에 호출된다면 교착 상태를 유발할 수 있다.