남이 읽는 CS/운영체제

[운영체제 5편] 데드락이 무엇인가

배발자 2022. 3. 22.
반응형

 

안녕하세요~ 개발자 배씨입니다!!

저번 시간에 뮤텍스와 세마포어에 대해서 알아보았어요 

이번 시간에는 "Deadlock(교착상태)"에 대해서 알아보려고 해요. 

 

교착상태 그게 뭐지..? 생각하실 수 있어요. 저번시간에 예를 들었었죠?? 

화가 "배씨"  화가 "이씨"가 있어요.

그리고 "배씨" "이씨"는 그림을 그릴려고 작업실(임계구역)에 들어가서 물감(공유자원), 붓(공유자원)을 각각 하나씩 집었어요.  

"배씨" 물감을 들었고 "이씨" 을 들고 서로 필요한 도구를 기다리고 있는거에요.

"배씨" 이 필요하니까 을 기다리고 있고, "이씨" 물감이 필요하니까 물감을 기다리고 있는거죠. 

 

즉, "둘 이상의 프로세스가 자원을 점유한 상태에서 서로 다른 프로세스가 점유하고 있는 자원을 요구하며 무한정 기다리는 현상"이 발생한다는 거에요!

 

이러한 현상을 "Deadlock(교착상태)"이라고 부릅니다. 

 

자! 이제 운영체제 용어로 들어가봐요! 

 

프로세스 P1이 임계구역에서 자원 A를 소유하고 있고 자원 B를 소유하려는 순간에 

문맥교환이 일어나서 프로세스 P2가 임계구역에 들어와요. 그리고 자원 B를 소유하고 자원 A를 소유하려는데 

이미 프로세스 P1자원 A를 소유하고 있어서 기다려야하는 상황이에요 

그래서 P1과 P2가 상대가 가지고 있는 자원만을 기다리게 되는거죠. 

 

데드락의 발생 조건으로는 4가지가 있어요! (싸가지 ㅎ)

이 조건 4가지 중에 하나라도!!! 단, 하나라도 조건을 족시키지 못한다면 교착상태가 일어나지 않아요. 

 

4가지 조건은 상호배제, 점유와 대기, 비선점, 순환대기라고 부릅니다. 

저는 상점비순으로 외우고 있어요! 

 

한번 들어가봅시다!!

 

1. 상호배제 (Mutual Exclusion) 

상호배제는 프로세스들이 자원을 배타적으로 점유하고있고 다른 프로세스들이 자원 사용이 불가합니다. 

한번에 한 프로세스만이 자원 사용이 가능하다는 겁니다. 즉, 자기가 소유하고 있는 자원을 다른 놈이 "좀 쓸래!!" 하고 애교 부려도 "싫어" 하는거에요~

 

2. 점유와 대기 (Hold and wait) 

점유와 대기는 자원을 가진 프로세스가 다른 자원을 기다릴 때 보유 자원을 놓지 않고 계속 가지고 있어요.

즉, 필요한 다른 자원 B를 갖기위해 자신이 들고있는 자원A를 갖다 버리고 B를 가지러 가는게 아니라는거에요!

 

3. 비선점 (No preemption) 

비선점에 관련돼서는 나중에 스케쥴링에 대해 포스팅할 때 설명드릴텐데 

비선점은 프로세스가 자원을 가지고 있을 때, 자원을 스스로 내어놓을 뿐 강제로 빼앗기지 않는다는거에요.

즉, 자기가 소유하고 있는 자원을 다른 놈이 뺏을려고 힘을 가해도 절대 뺏기지않게 꽉 붙잡는거죠. 

 

4. 순환대기 (Circular Wait) 

환형대기는 사이클이 형성된 상태로 기다리는 상황이에요. 

아래 그림과 같이 사이클 형태로 서로 빠져주기를 기다리는 거죠.

누구 양보없이 서로 나아가려는 방향만 바라보고 계속 기다리는거에요. 

 

 


 

조금 지루하시죠..? 여러분들은 위의 사진 상황에서 어떻게 하실건가요??

저는 앞에 차량과 정이 들어서 아무도 못끼어들게 딱 달라붙어 있어요. 뭐.. 데드락이 발생하는 원인 제공자죠 ㅎ

 

자! 이제 데드락을 처리하는 방법에 대해서 설명드릴거에요! 

예방,  회피 , 탐지 및 복구, 무시가 있어요 하나하나 살펴봅시다:)

 

1. 예방 (Prevention)

말 그대로 예방 하자는거에요. 데드락이 발생되지 않게 알고리즘을 짜는거죠. 

즉, 프로그램을 개발하는 개발자 역할인거죠. 

아까 위에서 "상점비순" 언급했었는데 그 중에서 하나 이상을 부정하자는 거에요! 

1. 상호배제 부정  
 - 읽기 전용 파일과 같은 공유 자원을 사용.

2. 점유와 대기 부정
 - 프로세스 대기를 없애기 위해서 프로세스가 실행되기 전에 필요한 모든 자원 할당. (자원낭비)
 - 자원을 점유하지 않고 있을 때에만 다른 자원을 요청할 수 있도록 함. (기아상태 될 수 있음) 

3. 비선점 부정
 - 모든 자원에 대한 선점 허용.
 - 프로세스가 할당받을 수 없는 자원을 요청하는 경우, 기존에 가지고 있던 자원을 모두 반납하고 새 자원과 이전 자원을 얻기 위해 대기. (자원낭비) 

4. 순환대기 부정
 - 자원에 고유한 번호를 할당해서 번호 순서대로 자원을 요구. (자원 낭비) 

단점 : 교착 상태 발생 조건 중 하나를 제거하는 것은 자원 낭비가 심함. 

 

2. 회피 (Deadlock Avoidance)

데드락이 빠질 가능성이 있는지 없는지 OS가 검사를 하고 빠질 가능성이 없을 경우에만 줘서 문제 발생을 피하는거에요. 즉,  "자원을 줄게! 음 그전에 데드락 문제가 발생하지않나..? 음.. 없구나~ 응 줄게!" 이러는 거죠. 

회피 관련돼서는 "은행원 알고리즘"을 예로 들어서 설명드릴게요. 바로 밑에 그림으로 설명해드릴거에요!

일단 보류! 

 

3. 탐지 및 복구 (Detection and recovery)

이 방법은 OS가 자원을 달라는 대로 주면서 주기적으로 데드락에 빠졌는지 검사를 해요. 

만약 데드락에 빠졌다면 바로 전 상태로 회복하면 되는거죠. 근데 이게 데드락이 발생한 것을 보고 전 상태로 돌려주려고 하니까 이것도 문제인거에요. 프로세스/스레드 중에 하나를 죽여서 죽은 놈이 갖고 있던 자원을 던져줘야하는 거죠. 또 매번 데드락이 발생했는지 체크하는 것도 복잡한 알고리즘을 거쳐요 그래서 이 방식도 오버헤드가 큽니다. 

 

4. 무시 

그냥 말 그대로 무시하는거에요. 특별한 조치를 취하지 않는거죠. 

사실 앞서 설명드린 데드락의 필요조건 4가지(상점비순) 기억나시죠? 근데 이 4가지를 모두 만족한다고 해서 교착상태가 반드시 일어나는 것이 아니에요. 교착상태는 드문 상황이기 때문에 예방과 회피기법을 프로그램에 넣게되면 시스템의 처리량과 효율성을 떨어뜨릴 수 있답니다. 그렇게 된다면 그게 더 성능면에서 안좋다는 거죠.

그니까~ 프로그램이 작동을 멈추거나 오류가 발생하면 사용자가 직접 프로세스를 종료하는거죠. 대부분 운영체제가 무시 기법을 사용하고 있다고 하네요! 


자 이제 아까 언급했었던 회피 방법에서의 은행원 알고리즘을 한번 알아볼까요?!?! 

오랜만에 그림을 한번 그려봤습니다! 그림을 보고 잘 이해해주세요 

 

먼저 BANK(은행)에 현재 "10라"가 있다고 가정해봐요~ 그리고 A와 B와 C라는 친구가 있는데 그 친구들은 각자 "5딸라", "4라", "6라"가 있어야 작업을 할 수 있어요. 근데 세 사람 모두 돈이 없어서 은행한테 돈을 빌리려고 합니다. 그리고 각자 작업이 끝나면 은행에게 빌렸던 돈을 고대로 반납을 해야한다고 가정합시다

자 BANK에서 A와 B와 C한테 "3딸라"씩 준다고 가정해봐요 ~ 그러면 BANK는 1딸라가 남고 나머지는 3딸라씩 가지고 있겠네요!! (C 친구는 좀 화가 많이 나있어요 ㅎㅎ) 자 여기서 은행은 생각을 합니다. B는 "4딸라"가 필요했는데 그러면 B한테 나머지 1딸라를 줘볼까? 라고요

 


 

그러면 B는 현재 4딸라가 되었으니까 자기가 하고자 하는 작업을 처리할 수 있겠죠?

 


 

B는 자기 할 일이 끝나고 빌렸던 "4딸라"를 은행에 반납해요. 그러면 은행은 "4딸라"를 가지고 있겠죠??


그리고 은행은 다시 생각을 합니다. 지금 4딸라가 있으니까 둘 중 누구한테 줘도 그 친구는 작업을 할 수 있겠죠? C친구가 화가 많이 났으니까 C한테 먼저 줘볼게요 ㅎㅎ 그러면 C는 "6딸라"를 가지게 되고 BANK는 "1딸라"가 남겠죠. 그리고 C는 그 돈 가지고 작업을 합니다. 


C가 작업을 끝내고 은행에 "6딸라"를 반납합니다. 그러면 은행은 "7딸라"를 들고 있겠죠?


그리고 은행은 나머지 A라는 친구한테 "2딸라"를 주면서 A가 작업을 할 수 있게 해주는 거죠. 그리고 A도 작업이 끝나면 돈을 반납하게 될거고 은행은 처음 그대로 "10딸러"가 남게 됩니다.

 

이렇게 쿵짝쿵짝~ 해서 모든 사람이 작업이 처리할 수 있는 상태를 "안전상태"라고 해요~ 

 

자! 다시 처음 조건으로 돌아와볼게요!

만약 처음에 은행이 A와 B한테는 "3딸라"를 주고 C는 계속 화를 내니까 C한테는 "3.5딸라"를 줬다고 가정해봐요. 

그러면 은행은 "0.5딸라" 가 남았잖아요? 여기서 어느 누구한테 "0.5딸라"를 줘도 그 사람은 자신이 원하던 돈을 충당하지 못하죠?? 즉, 돈이 부족하기 때문에 작업을 할 수가 없는거에요. 그러면 그 은행은...?

 

 

데드락인거죠. 이러한 상태를 "불안전 상태" 라고 부릅니다. 

은행이 어떠한 순서로 돈을 나눠줘도 세 사람 모두 처리할 수 없겠죠. 불안전 상태는 교착상태의 필요조건이랍니다.  

 

그렇기 때문에 은행가 알고리즘은 교착상태에 빠질 가능성을 이전에 체크해서 첫번째 예시로 들었던 방식으로 돈을 나눠줬을거에요. C가 화나있더라도 0.5달라를 더 주는 선택을 하지 않겠죠. 

 

그치만 이것도 단점이 존재합니다 ㅠ 

각 프로세스가 가지고 있어야 할 최대 자원의 개수를 미리 알아야하고 불안정 상태를 방지하기위해 처리하는 알고리즘이 엄청 복잡하다고 해요. 이런저런 문제 때문에 오버헤드가 크다는 단점이 있어요.  


 

자 데드락에 대해서 어느정도 이해가 되셨을거라고 생각됩니다~  근데 조~금 의문점이 들지 않나요?? 

 

지금껏 뮤텍스든 세마포어든 그리고 데드락이든 모두 공유 자원의 접근과 관련이 있잖아요?? 

근데 제가 분명 프로세스는 독립관계라서 공유하는 공간이 없다라고 말한거 기억나시나요?

 

프로세스는 독립적인데 공유자원에 접근해서 발생되는 이러한 문제점을 왜 포함시키냐? 라고 의문점이 드셔야합니다. 

 

하지만 프로세스도 서로 공유할 수가 있어요. "IPC" 라는건데, 이 놈을 알아보기 전에 먼저 배워야 할게 있습니다. 그 얘기는 다음 시간에 포스팅 하도록 할게요~

 

이번 포스팅은 시간이 많이 걸렸네요 ㅎㅎ.. 광고 한번씩 눌러주면.. 수고비로 몇십원.. 받거든요.. (실수로 클릭 한번씩 해볼까요..?)

 

반응형

 

 감사합니다 :) 

 

 

 

 

반응형

댓글