작성
·
308
1
안녕하세요. 항상 좋은 강의에 감사드립니다.
ReaderWriterLock 강의 10분 전후로 나오는 예시에서 이해가 어려운 부분이 있어 문의드려요.
RPG의 퀘스트를 아래와 같이 예시를 들어주셨습니다.
- 퀘스트에는 3개의 고정 보상이 존재한다.
- 운영 정책(이벤트 등)에 따라 추가 보상이 존재할 수 있다.
- 평소에는 Lock이 필요하지 않지만, 추가 보상이 있을 때는 한시적으로 Lock이 필요하다.
여기서 궁금한 점이,
1) 서버가 Lock이 필요한 이유는, 멀티스레드 환경에서 퀘스트 추가 보상을 지급하는 절차가 한 스레드에 의해 이루어지도록 하기 위한 게 맞나요?
2) 1번이 맞다면, 평상시에 Lock이 필요없는 이유는 무엇인가요? 만일 퀘스트 보상을 서버에 요청하여 받는 형태라면 항상 Lock이 필요할 것 같아서요.
답변 3
6
네. 혹시 오해의 소지가 있을까봐 추가 설명을 드리자면
결과적으로 데이터를 쓸 때가 문제인 것은 맞지만,
데이터 Write하는 부분이 들어가면 Read 쪽에도 같이 락을 걸어줘야 합니다.
또한 일반 lock을 사용하면 상호배타적 특징때문에
같은 Read끼리도 서로 대기 상태가 일어나는데,
ReadWrite Lock을 활용하면 이런 부분을 개선할 수 있습니다.
3
1)
아닙니다. 일련의 절차는 (별도의 처리가 없다면)
당연히 하나의 쓰레드가 담당해서 끝까지 처리하고 아무런 문제가 되지 않습니다.
2)
멀티쓰레드 환경이라고 해서 꼭 Lock이 필요한건 아닙니다.
쓰레드 사이에 공유하는 데이터가 있는 경우 한정해서 문제가 일어나는데,
정확히는 모든 공유 데이터가 문제를 일으키진 않고
쓰기(Write) 연산이 들어가는 경우만 조심하면 됩니다.
만약에 퀘스트에 3개 고정 보상이 존재하고 여기서 100% 바뀌지 않는다면
다수의 쓰레드가 DataManager를 참조해서
동시 접근하더라도 아무런 문제가 되지 않습니다.
문제가 되는 부분은 한쪽에서는 데이터를 읽고,
다른 쪽에서는 데이터를 수정하는 상황입니다.
1초마다 보상이 바뀌는 극단적인 상황인데,
현재 보상 목록은 [1, 2, 3]번이고 이를 [5, 6, 9]로 교체한다고 가정해봅시다.
그런데 락 없이 접근할 경우
특정 쓰레드 A에선 [1, 2..] 까지 읽는 도중
다른 쓰레드 B가 리스트를 조작하는 바람에 데이터가 뒤섞여
[1, 2, 6, 9]라는 존재하면 안 되는 보상 목록을 긁어올 수 있다는 얘기가 됩니다.
뭐 C#이라 이 정도에서 끝나겠지만 C++이라면 1, 2, 3에 해당하는 메모리까지 날려버리는 관계로
높은 확률로 크래시가 나겠죠.
0
아 그동안 전역 변수 _num에 한 스레드는 1을 더하고 한 스레드는 1을 빼는 것처럼 데이터를 쓸 때만 락을 걸면 되는거군요. 읽을 때는 여러 스레드가 접근해도 같은 내용을 읽어갈테니...
답변 감사합니다!