lock_guard 를 활용한다고 해서 세상 모든 dead_lock이 사라지지 않는다.

 

 

 

저번 단원에서 배운 ( lock_guard (RAII) : )  lock 해주고 unlock 안해줘서 생기는 ) DeadLock 은 정말 1차원적인 DeadLock이고 자주 생기지 않는다.

 

다른 이유 때문에 생기는 DeadLock이 많고, 실제 실무에서 예를 들자면,

 

MMO 서버에서 서버가 뻗는다면 가장 높은 확률로는 nullptr 크래쉬가 ( 포인터인데 nullptr를 잘 못 참조해서 뻗는 경우 ) 가 있고, DeadLock 문제도 상위권에 있는 문제이다.

 

오늘만 실습할 클래스를 하나 만들어보자.

 

 

 

 

쓰레드 t1 은 ProcessSave() 를 실행하면서 user lock을 걸고 있고 이 Lock 은 ProcessSave()  가 종료될때 lock_guard 에 의해 소멸자가 호출되면서 unlock 된다. (RAll 이론 ) 

 

반대로 쓰레드 t2 는 ProcessLogin() 함수를 실행하면서 account lock을 걸고 있는데 마찬가지로 ProcessLogin() 함수가 끝날떄 소멸자에 의해 unlock 된다.

 

두 함수 모두 다음 코드로 서로가 lock을 풀면 들어가려고 기다리고 있기 때문에 dead lock 이 걸렸고,

 

해결 방법은 간단하다.

 

1. 순서를 맞춰 주면 된다. 

 

t1을 account Lock 부터 걸어주던, 

t2를 user Lock 부터 걸어주던

 

둘 중에 먼저 들어간 mutex를 잡은 사람이 다른 것도 잡을 수 있게끔 하면 된다. 

 

그러나 멀티 쓰레드 환경에서 이렇게 순서를 맞춰준다는거 자체가 굉장히 어려운 일이다.

 

Dead Lock 이 짜증나는 이유는 어쩔때는 발생 하고 어쩔때는 발생하지 않기 때문에 짜증이 난다

위의 예시에서 Fun1() 이나 Func2() 의 for문의 반복횟수를 1로 줄인다면 발생하지 않을때가 많을 것이다.

그래서 개발 단계에서는 발견 못하다가 실제 live 상황에서 동접이 많아 질때만 발견할 가능성도 있다.

 

그렇다면 이 순서를 항상 맞춰 줄 수 있는 방법이 있냐? NO 

 

사람들이 많이 사용하는 방법이 있긴 하다.

 

mutex _mutex 를 바로 사용하는게 아니라 wrapping을 해서 별도의 class 로 만든 다음에 일종의 id를 부여해서 id가 큰애가 무조건 먼저해야되는 거처럼 꼼수를 이용해서 하긴 하는데, 이것도 정확하지는 않다. 

 

결론 부터 말하자면 Dead_lock은 뭔가 미연의 100% 방지하고 그런게 아니라 조심하면서 사용해야한다.

 

한 가지 팁은 

 

 

 

강의 후반부에 강사님는 그럼 어떻게 이걸 해결하는지 직접 강의로 듣기

 

 : graph 알고리즘을 이용해서 dead_lock을 탐지한다. ( 싸이클이 생기면 ) 

 

+ Recent posts