해결된 질문
작성
·
115
1
CAS 의사코드 보면서 든 의문입니다. _locked와 expected가 같을 때 expected = _locked을 하는 작업이라든가 필요없을 것 같은 작업들이 있는 것 같아 아래와 같이 작성하여보았습니다. 작동은 똑같이하는데 문제가 생길 것이 있을까요?
bool check(bool& locked)
{
if (!locked)
{
return locked = true;
}
else
{
return false;
}
}
class SpinLock
{
public:
void lock()
{
/*bool expected = false;
bool desired = true;*/
// CAS (Compare-And-Swap)
// 의사 코드
/*if (_locked == expected)
{
expected = _locked;
_locked = desired;
return true;
}
else
{
expected = _locked;
return false;
}*/
/*while (_locked.compare_exchange_strong(expected, desired) == false)
{
expected = false;
}*/
while (check(_locked)) {}
}
void unlock()
{
_locked = false;
}
private:
bool _locked = false;
//atomic<bool> _locked = false;
};
답변 1
0
네 안됩니다.
싱글쓰레드 코드에 익숙했던 뇌를
말랑말랑하게 바꿔서 멀티쓰레드에 적응하는게 중요합니다.
CAS의 핵심은 단순히 의사코드가 아니라
의사코드가 '한번에' 이루어진다는 점입니다.
이 부분에서 if (!locked) 체크하는 부분과
return locked = true 하는 부분이 둘로 나뉘어져 있습니다.
따라서 다수의 쓰레드가 거의 동시에 접근해서 타이밍이 맞아 떨어지면
if(!locked)를 여럿이 통과해서 locked = true로 통과할 수 있습니다.
그러면 사실상 상호배타적인게 아니라 lock을 여러 쓰레드가 획득할 수 있다는 얘기가 되는거라 모순이죠.