작성
·
73
0
ReadLock 코드
uint32 expected = (_lockFlag.load() & READ_THREAD_MASK);
if (_lockFlag.compare_exchange_strong(OUT expected, expected + 1)) return;
WriteLock 코드
const uint32 desired = ((LThreadId << 16) & WRITE_THREAD_MASK);
...
uint32 expected = EMPTY_FLAG;
if (_lockFlag.compare_exchange_strong(OUT expected, desired))
{
_writeCount++;
return;
}
Write할 때 lockFlag를 LThreadId << 16로 저장하기 때문에 첫 비트 ~ 15비트까지는 0으로 초기화가 될것입니다.
ReadLock에서는 Read용 Mask를 쓰는데 그럼 Write에서 초기화해준 lockFlag를 볼 수 없어서 항상 참값이 나와 expected + 1로 수정되는거 아닌가요??
다른 스레드가 Write하고 있을 때 Read를 허용하는것인지 궁금합니다.
답변 2
0
0
안녕하세요, 인프런 AI 인턴입니다. dpcks5959님.
주신 코드에서 ReadLock과 WriteLock의 상호작용에 관한 질문을 주셨군요. 비트 마스크와 compare_exchange_strong
을 사용하는 점에서 혼란이 생길 수 있습니다. 이 질문에 대한 해결을 돕기 위해, 몇 가지 개념과 기존의 Q&A 링크를 공유드리겠습니다.
비트 마스크 및 시프트:
LThreadId << 16
로 상위 비트를 사용하여 WRITE_THREAD_MASK
에 의해 특정 Thread ID 값을 저장합니다. 이런 방식으로 기존의 lockFlag
의 하위 비트는 영향을 받지 않게 됩니다.ReadLock 처리:
READ_THREAD_MASK
는 하위 비트만을 검사합니다. 즉, WriteLock
이 설정된 상위 비트는 염두에 두지 않는 방식을 사용하며, expected
값이 어떤 변화를 겪는지를 바탕으로 간접적으로 Write 상태를 판단합니다.따라서, 만약 다른 스레드가 Write Lock을 가지고 있을 경우에는 compare_exchange_strong
이 실패하게 되고, 반복적으로 동일한 동작을 수행합니다. 결국 ReadLock이 성공하려면 WriteLock이 풀린 상태여야 합니다.
다른 사용자가 비슷한 주제로 질문한 내용과 답변을 확인해 보시면 도움이 될 것입니다. 특히 명확한 예제와 설명이 첨부되어 있어 큰 도움이 될 것입니다:
이 질문과 답변은 reader-writer lock의 비트 연산과 마스킹의 사용에 대한 이해를 돕기 위해 작성된 좋은 사례입니다. 설명이 직관적이라면 이해하는 데 많은 도움이 될 것입니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.