인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

bs Jeon님의 프로필 이미지
bs Jeon

작성한 질문수

[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버

DeadLock 탐지

Deadlock detector 동작 방식 및 정책

작성

·

532

2

안녕하세요.

Deadlock detect 컨셉에 대하여 문의드리고자

글을 쓰게되었습니다.

Detect 컨셉을 확인하는중 아래와 같이

논리적으로 데드락이 발생하지 않는 상황이더라도

Detect 로직에 의해 크래쉬가 나게되는데

실무에서는 보수적으로 이런  부분 역시 디텍하여

수정을 강제하는것이 일반적인가요?

아래 락을 거는 관계도라고 하였을때

코드적으로 a -> b->c 가 한꺼번에 연쇄적으로

수행될수 없는 상황이라고 했을때에도

디텍터에서는 사이클로 판단하여 크래시를 발생시킴

Class a -> class b

Class b -> class c

Class c -> class a

답변 1

2

Rookiss님의 프로필 이미지
Rookiss
지식공유자

코드 로직상 혹은 타이밍 덕분에 크래시가 나지 않더라도

Class a -> class b
Class b -> class c
Class c -> class a

이렇게 순환 구조로 락을 잡는 것 자체가 문제입니다.
코드를 만들 때는 단순 현재만 볼게 아니라
나중에 누군가가 (신입이 될 수도) 와서 수정하는 것까지
멀리 내다보고 고려를 해야 합니다.
코드가 조금이라도 수정되거나, 함수를 다른 곳에서 호출한다거나 하면

없던 버그가 터질 수도 있겠죠.
따라서 순환 구조가 일어나는 것은 바로 잡아줄 필요가 있습니다.


그러나 그와는 별개로 [실무에서 무엇을 사용하는지]를 여쭤보셨는데
대부분의 프로젝트에서는 데드락을 탐지하는 '무엇인가
'를 넣어놓지는 않습니다.

그나마 몇몇 프로젝트에서는 lock마다 id를 부여해서,
hierarchy가 동일한 id끼리는
id가 낮은 순서대로 잡지 않으면 크래시나게 한다거나 하는 코드를 넣어놨는데요.
(ex. UserManager=1001번, User=1002번, ...)
여기서 hierarchy 1000번대는 하나의 그룹으로 인식해서,
User->UserManager 순서로는 락을 잡을 수 없다거나,
하는 탐지 코드를 넣어놓긴 했습니다.
근데 수동으로 id를 관리하는게 끔찍하고,
서로 다른 hierarchy (1000번대와 3000번대)끼리는 해당하지 않으므로
제 입장에선 거의 실용성이 없었다고 봅니다.

강의에서 등장하는 LockDetector는
딱히 실무에서 경험한 방법은 아니고,
이전에 라이브 프로젝트에서 일할 때 은근 자주 발생하는 데드락 이슈를
개발 단계에서 어떻게 잡을 방법이 없을까 고민하다가
넣은 코드입니다.

데드락이 원인 파악은 쉽지만,
이미 세월이 쌓여 작성된 코드가 너무 많아버리면
완벽하게 수정할 방법이 딱히 없고
그냥 적당한 땜빵처리밖에 못하는 상황까지도 갑니다.

bs Jeon님의 프로필 이미지
bs Jeon
질문자

네 이해하였습니다.

감사합니다^^

bs Jeon님의 프로필 이미지
bs Jeon
질문자

한가지 더 궁금한부분이 있는데요.

강의 마지막 부분에 스택을 tls영역으로 변경하셨는데요. 

이렇게되면 오히려 멀티스레드의 처리순서에 의한  미묘한 순간의 사이클을 디텍트하지못하는게 아닌가요?(미묘한 타이밍에 의하여 서로 다른 스레드의 락을 거는 문제)

Rookiss님의 프로필 이미지
Rookiss
지식공유자

그렇지 않습니다.
lock을 잡는 history (1번->3번과 같이)는 누적이 되면서 합산되고
그 합산된 결과에서 사이클이 있는지 판별하기 때문에 미묘한 순간은 존재하지 않습니다.
애당초 lockStack을 관리하는 이유는 (마지막에 잡고 있던 락 -> 현재 새로 잡은 락)
이 순서를 추적하기 위함입니다.
그러니 스택을 TLS로 빼주지 않으면 오히려 문제가 되는게,
각 쓰레드마다 현재 잡고 있는 lock이 다 다를텐데
이 순서가 꼬여서 엉뚱한 정보로 들어가게 되겠죠.


bs Jeon님의 프로필 이미지
bs Jeon
질문자

답변 감사합니다.

생각했던 부분이 특정 thread에서 하나의 lock 잡고 있는 경우 history에

합산되지 않는게 문제가 되지 않을까 하였는데, 답변과 함께 고민하니

하나의 lock만 잡고 있는 thread인 경우 history에 누적되지 않는다고 하여도

문제가 없겠네요.( 하나의 Lock을 잡은 뒤에는 해당 스레드가

dead lock(외부 Lock)에 의해 멈출 일이 없기 때문에 정상적으로 Unlock을 하게 될것이고 

이로 인해 해당 lock으로 인한 DeadLock을 만들지 않는다고 보장할 수 있으므로 history에

넣을 필요없음)

bs Jeon님의 프로필 이미지
bs Jeon

작성한 질문수

질문하기