작성
·
35
0
// CAS는 automic하게 수행
while (_locked.compare_exchange_strong(expected, desired) == false)
{
// expected에 false를 대입하는 부분도 automic하게 수행?
expected = false;
}
CAS 부분은 automic하게 수행되는 걸 이해했는데, expected에 false를 대입하는 부분도 CAS와 한 묶음으로 automic하게 수행될까요?
그렇지 않다면, 어떤 쓰레드가 lock을 획득한 상태(_locked가 true)에서,
A라는 쓰레드가 CAS 수행 후, expected가 true로 변경, 이어서 expected에 false를 대입하려다가 B라는 쓰레드가 CPU 점유.
B라는 쓰레드는, expected가 true인 상태에서 CAS 수행 후, while문 탈출. 이미 다른 쓰레드가 접근하고 있는 critical section 접근 가능. 이라는 시나리오가 나올 수 있을 것 같은데, 어떤 부분이 잘못 생각하고 있는 지점일까요?
답변 2
1
CAS 부분은 automic하게 수행되는 걸 이해했는데, expected에 false를 대입하는 부분도 CAS와 한 묶음으로 automic하게 수행될까요?
아닙니다!
이라는 시나리오가 나올 수 있을 것 같은데, 어떤 부분이 잘못 생각하고 있는 지점일까요?
bool expected;는 함수 내부에 있는 지역변수이기 때문에,
멀티쓰레드 환경이라고 하더라도 전혀 무관하고 경합 대상이 아닙니다! (스택 메모리 사용)
0
안녕하세요, 인프런 AI 인턴입니다. kudo님.
질문해주신 C++에서의 SpinLock 구현에 대한 의문점에 대해 답변드리겠습니다. 여러분이 작성한 반복문은 CAS(Compare-And-Swap) 연산을 사용하여 Spinlock을 구현하고 있습니다. 이 때, expected = false;
부분이 atomic하게 수행되지 않는지에 대해 의문을 가지셨습니다.
CAS는 하드웨어에서 support되는 연산으로, atomic하게 수행됩니다. 하지만 expected = false;
는 일반적인 연산이므로 atomic하지 않습니다. expected
는 스레드의 로컬 변수로 존재하기 때문에, 스레드마다 독립적으로 사용됩니다. 즉, 다른 스레드와의 상호작용에서 멀티스레드 환경에서의 실행 순서에 영향을 받지 않습니다.
다음과 같은 추가 설명을 참고하시면 이해에 도움이 되실 것입니다:
CAS의 Atomic성: 클래스를 통해 구현된 CAS 메서드는 주어진 메모리 위치에 대해 값을 비교하고, 원하는 값으로 바꾸는 과정을 한 번의 원자적 연산으로 보장합니다. 이는 두 스레드가 동일한 메모리 주소에 접근하여 동시에 수정할 수 없음을 의미합니다.
expected의 사용: expected
는 항상 현재 스레드의 지역 변수로 간주됩니다. 따라서 다른 스레드가 이 값을 볼 수 없습니다. 현재 스레드에서만 expected
의 값을 수정하며, 해당 값이 CAS 연산 결과를 위한 참조 변수가 됩니다.
잘못된 부분: 질문에서 말씀하신 시나리오에서는 expected
가 true
로 설정된 바로 직후에 false
로 설정하기 전 상태에서, 다른 스레드가 올 수 있는 이슈를 말씀하셨습니다. 하지만 다른 스레드가 expected
를 참조할 수 없기에 이 같은 시나리오는 발생하지 않습니다. 중요한 것은 CAS 연산 그 자체가 실패하였을 때 while 루프내에서 expected
를 업데이트하며, 다른 스레드의 상태에 영향을 주지 않는다는 것입니다.
이와 관련하여 유사한 질문에 대한 기존 논의들을 추천드리니 확인하시면 더 도움이 되실 것입니다:
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.