작성
·
67
·
수정됨
0
안녕하세요.
나중에 프로젝트 진행하실 땐 lock stack을 TLS로 관리해서 스레드마다 스레드 id가 관리되도록 하신다 말씀하셨습니다. 여기에서 생긴 궁금증입니다. 스레드 id가 부여될 때, 감소하지 않고 증가하는 nameToId().size()로 만들어지는 이상 모든 id가 고유할 거라고 생각합니다.
id를 통해서 lockHistory에서 value(set객체)를 꺼냅니다. lockHistory는 TLS에서 관리되지 않는 전역 객체입니다(애초에 그러면 안 되겠죠. 전역적으로 사이클 여부를 탐지해야 하니까요!).
스레드 id가 유일한 이상 lockStack을 TLS에서 관리하나 전역으로 관리하는 것이 차이가 없을 것 같은데, 강의 후반에 새로 영상을 추가하시어 '스레드마다 잡고 있는 락이 다르기 때문에 TLS로 관리해야 한다'고 말씀하신 이유가 궁금합니다!
id가 전역적으로 1,2,3,4,5,6..이렇게 증가하거나 스레드 별 공간에서 {1,2..} {1,2...} {1,2...} 의 차이 정도로만 생각되어 어떤 본질적인 차이가 있는지 알고 싶습니다!
p.s 수업에서 진행한 테스트 코드에서도 문제가 없었던 이유도 궁금증에 한몫을 했습니다.
답변 1
0
말 그대로입니다.
ThreadA와 ThreadB는 각각 따로 실행되므로
A는 1->3->3->4->9 순서로 락을 잡고
B는 2->5->3->1->9 순서로 락을 잡아도 전혀 이상하지 않은 상황이므로,
각기 TLS에 락 잡은 상황을 따로 남기는 것입니다.
즉 현재 Lock을 만날 때까지, Lock을 잡고 있는 상태가 쓰레다마다 다를 수 있다는 얘기입니다.
넵 맞습니다! lock stack을 TLS 별로 관리하면 스레드 별로 락을 잡고 있는 상태를 파악할 수 있습니다.
CheckCycle 안에서 Dfs가 동작하는 걸 보면 데드락 탐지는 lockHistory를 통해서 하고 있고, 만약 스레드 id가 0, 1, 2 세 개가 생겼다면 락 스택을 전역으로 관리할 때는 {0, 1, 2}로 저장이 되고 TLS에서 관리될 때는 각 TLS에 {0}, {1}, {2}로 저장되는 차이 말고는 데드락 탐지에 있어서의 로직 변화가 없는 같다 판단했습니다.
역방향 간선이 발견되어 로그를 남길 때도 idToName 객체만 있으면 순환을 할 수 있기 때문에, 데드락 탐지 강의에서 락 스택을 TLS로 관리하는 건 스레드 별 락 현황을 파악할 수 있다는 것 말고는 다른 특이점이 보이지 않는 것 같은데 맞을까요?
감사합니다!