두 개 이상의 작업이 서로 상대방의 작업이 끝나기 만을 기다리고 있기 때문에 결과적으로 아무것도 완료되지 못하는 상태를 말한다.
프로세스가 자원을 얻지 못해 다음 처리를 하지 못하는 상태로, 시스템적으로 한정된 자원(CPU,메모리,파일,프린터 등)을 여러 곳에서 동시에 사용하려고 할 때 발생한다.
예를들어, 각기 다른 프로세스 2개가 두개의 자원을 동시에 사용해야만 실행된다고 할때, 서로 원하는 자원이 상대방에게 할당되어 있어서 상대방이 실행 되어 그 자원을 쓸 수 있을때까지 무한정 기다리는 상태를 데드락이라고 말한다.
💡 데드락 같은 상황
선생님이 철수랑 영희한테 청소를 시켰다.철수는 청소도구함에서 빗자루를 챙기고, 영희는 쓰레받기를 챙겼다. 이제 청소를 시작하자.철수가 빗자루질을 하고 그걸 담으려고 하는데 쓰레받기가 없다. 영희가 다 쓰길 기다려야겠네?라고 생각하며 기다린다. 철수는 빗자루를 손에 쥐고 기다렸다. 영희는 영희대로 철수가 빗자루질을 다 해야 내가 청소를 마칠 수 있겠구나?라고 철수가 빗자루를 다 쓰길 기다린다. 쓰레받기를 손에 꼭 쥔 채 말이다.
→ 애네들 집에 못가게 생김..선생님은 속이 터짐
초기 컴퓨터는 한번에 하나만의 작업을 할 수 있었다.
그런데 컴퓨터가 발전하면서 한번에 여러 작업을 하게 하고 싶어졌다. 예를 들면, 음악을 듣으면서 뉴스 읽는 것을 동시에 하는 것이다.
근데 "CPU가 하나인데 어떻게 동시에 처리하지?"라는 문제가 있었고,
똑똑한 공학자들은 컴퓨터는 무지 빠르니까 두가지 일을 이거했다 저거했다를 엄청 빨리 반복하면 사람의 지각능력으론 동시에 하는 것처럼 보이지 않을까?라는 아이디어를 냈고, 그래서 나온것이 멀티프로세싱과 멀티쓰레딩이다. 데드락은 바로 이런 다중프로그래밍 환경에서 여러 프로세스(혹은 쓰레드)가 간섭하면서 생기는 문제를 말한다.
해결방법에는 크게 예방과 회피로 두가지 방법이 있다.
교착 상태 발생 조건 중 하나를 제거하면서 해결하는 방법이다. (자원 낭비 심함)
여러 프로세스가 자원을 공유하도록 한다.=> 현실적으로 불가능
현재 필요하지 않음에도 자원 소유, 필요한 자원을 파악하기 위한 비용이 발생한다. → 자원 효율성이 낮다. 기아 상태가 발생할 수 있다.
프로세스의 자원이 사용 끝나기 전에 선점될 수 있게 한다. 즉, 프로세스가 다른 자원을 요구할 때 즉시 할당 받을 수 없다면, 점유하고 있는 모든 자원을 반납하고 기다린다. ( 내가 갖고 있던 자원을 놓고(비선점) 자원이 사용가능할때까지 기다리는 것 )
그리고, 반납한 자원과 필요로 한 자원 모두를 사용 가능할 때 프로세스는 재실행된다. 이 방법은 cpu register, memory space같은 자원이 쉽게 선점되고 할당되는 경우에 종종 쓰인다. 하지만, 뮤텍스락이나 세마포어에서는 일반적으로는 사용되지 않는다.
자원에 고유번호 할당 후 순서대로 자원 요청하게 한다.노는 자원이 발생할 수 있다.
ex) 프로세스는 순서의 증가 방향으로만 자원 요청 가능
R1, R2, R3, R4
P1 (R1, 2, 4 모두 필요)
P2 (R1, 3 모두 필요)
P1이 먼저 R1을 사용하면, P2는 R1을 못 쓰기 때문에 P2가 실행 불가. 따라서, 자원 3는 아무것도 하지 않는다.
=> 자원 사용의 효율성이 떨어지고 비용이 많이 드는 문제점이 있다.
교착 상태 발생 가능성을 검사하여 피하는 방법이다.
ex) 은행원 알고리즘(Banker's Algorithm)
safe state와 unsafe state로 나누어 safe state일 때만 자원 할당하는 방법으로프로세스가 자원을 요구할 때, 자원 할당 후에 안정 상태로 남아있게 되는지 사전에 검사하여 교착 상태 회피하는 방법이다.
안정 상태면 자원 할당, 아니면 다른 프로세스가 자원 해지까지 대기하게 한다.은행이 항상 모든 고객에게 현금을 대출해주는데 서 유래되었다. 은행(os)은 최소한 고객(프로세스) 한 명에게 대출할 정도의 돈(자원)이 있어야 한다.그렇지 않으면 은행은 불안정 상태 ( 데드락이 발생 가능한 상태 )임을 판단된다.
데드락이 이론적으로는 이해가 가나, 실제로 피부에 와닿지 않아서 실제로 데드락으로 인해 문제가 발생하는 경우를 찾아보았다.
데이터베이스에서 발생하는 데드락의 경우가 많이 보였고, 이에 대해 설명하려고 한다.
데이터베이스에서 데드락(deadlock)이란, 여러개의 트랜잭션(Transaction)들이 실행을 하지 못하고 서로 무한적 기다리는 상태를 의미한다. 기본적으로 데이터베이스에서는 트랜잭션들의 ‘동시성’을 제어하기 위한 기법으로 로킹(Locking)을 사용한다. 이러한 로킹이 데이터가 엉망진창이 되는 것을 막아주겠지만 그 부작용으로 교착 상태를 일으킬 수 있다.
즉, 두 개 이상의 트랜잭션이 특정 자원(테이블 또는 행)의 Lock을 획득한 채 다른 트랜잭션이 소유하고 있는 잠금을 요구하면 아무리 기다려도 상황이 바뀌지 않는 상태가 되는 것을 말한다.
Oracle의 경우, Dead Lock을 감지하면 한쪽 Transaction을 풀어버리는 방법을 통해 해결한다. 트랜잭션 A의 마지막 UPDATE 내용에 오류가 발생되고 Commit을 먼저 하도록 유도합니다. 트랜잭션 B는 아직 Waiting 상태로 남아있고, 트랜잭션 A의 Commit을 기다리게 된다.
내 생각에 이 방법은 위의 deadLock 해결방법에서 예방의 3)비선점 부정과 4)순환 대기 부정을 사용한 방법이라 판단된다.