작성
·
70
·
수정됨
0
안녕하세요!
어제, 강의도 다 안 듣고 질문을 드린 바보 같은 저를 질책하며 강의를 다 듣고 제가 이해한 게 맞는지 확인을 좀 받고 싶습니다!
락 획득 정책을 말씀하실 때 살짝 이해가 안 가는 부분이 있었는데 동일 스레드일 때란 걸 알게 되고 나서는 이해에 큰 어려움이 없었습니다. 그래도 확인이 필요하다는 생각이 들었습니다! 각 항목을 번호로 구분해보겠습니다!
동일 스레드일 때의 정책이란 게 락을 획득 후 실행될 때는 사실상 싱글 스레드인 것처럼 생각해도 되겠더라구요
그렇다고 한다면 GameServer.cpp에서 테스트 코드 작성하실 때 ThreadWrite()일 때 TestPush(), TestPop()의 동작이 한 스레드에서 동작하는 건 당연히 문제가 안 되니까 W->W 혹은 W->R을 허용하는 게 이해가 됐습니다. 한 처리가 완료되고 나서 다른 처리로 넘어가니까요.
그렇다면 같은 논리가 적용될 것 같은데 R->W은 왜 안 되느냐에 대해서도 생각해봤는데요. 논리적으로 접근했을 때, 하나의 함수 내에서 읽기 연산 중에 쓰기 연산을 하는 건 단일 책임 원칙에도 위반될 뿐더러 이상한 코드가 나오더라고요. 가령 테스트 코드로 작성하신 TestRead() 안에 TestPush() 혹은 TestPop()을 넣어버리면 안 되니까요. 또한 데드락이 생기지 않기 위해서는 락을 거는 순서가 중요한데, w->r을 허용한 이상 r->w를 허용하면 데드락이 생기기 딱 좋다.
ReadLock에 대해서는, WriteLock을 잡고 있지 않은 다른 스레드는 ReadLock을 획득할 수 있다!
ReadLock의 주석에 "아무도 소유하고 있지 않을 때"라고 되어 있어서, 조금 헷갈렸는데요. 코드를 보면 마스킹해서 read_count만 확인하는 걸 보고 역시 ReadLock은 WriteLock을 잡고 있지 않은 스레드도 잡을 수 있구나, 카운트 올리는 것만 경합하는 거구나, 로 이해했습니다.
2년 전에 처음 강의를 들을 때 제대로 이해 안 하고 넘어갔다가 나중에 큰 화를 당했어서, 이번에는 확실히 이해하려고 하다 보니 코드에서 참 얻을 게 많다 느낍니다. 틀린 게 있으면 지적 부탁드립니다. 감사합니다!
답변 1
0
안녕하세요, 인프런 AI 인턴입니다. literate_t님.
강의 내용을 잘 이해하시려는 노력이 대단하십니다! 질문하신 사항들은 매우 세부적이고 정확한 이해를 위한 것이므로, 이를 통해 다른 수강생들도 많은 도움을 받을 수 있을 것 같습니다.
제가 이전에 강의 게시판에서 비슷한 질문과 답변들을 찾아본 결과, 몇 가지 추가적인 참고 자료를 제공해드리겠습니다.
통합적으로 요약하자면:
동일 스레드일 때의 정책: 맞습니다. 동일 스레드에서 연산이 수행되기 때문에 마치 싱글 스레드처럼 동작하게 됩니다.
W->W 그리고 W->R 허용: 하나의 스레드에서 연속적으로 Write와 Read를 수행하는 것은 문제가 되지 않습니다. 각각 처리 후 다음 연산으로 넘어가기 때문입니다.
R->W 불허: 읽기 중에 쓰기를 하는 것을 하지 않게 설계함으로써 데이터의 불일치 문제를 방지하는 것이 목적입니다. 단일 책임 원칙을 준수하고 이상한 코드 흐름을 피하기 위해서는 이런 제한이 필요합니다.
ReadLock의 동작: Write Lock이 없는 상태에서 Read Lock을 여러 스레드가 획득할 수 있습니다. 이는 데이터 읽기 작업에 있어, 다수의 읽기 연산이 동시에 안전하게 수행될 수 있다는 뜻입니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.