인프런 커뮤니티 질문&답변

태상규님의 프로필 이미지
태상규

작성한 질문수

[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버

SpinLock 질문입니다.

해결된 질문

작성

·

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

Rookiss님의 프로필 이미지
Rookiss
지식공유자

네 안됩니다.
싱글쓰레드 코드에 익숙했던 뇌를
말랑말랑하게 바꿔서 멀티쓰레드에 적응하는게 중요합니다.
CAS의 핵심은 단순히 의사코드가 아니라
의사코드가 '한번에' 이루어진다는 점입니다.



이 부분에서 if (!locked) 체크하는 부분과
return locked = true 하는 부분이 둘로 나뉘어져 있습니다.
따라서 다수의 쓰레드가 거의 동시에 접근해서 타이밍이 맞아 떨어지면
if(!locked)를 여럿이 통과해서 locked = true로 통과할 수 있습니다.
그러면 사실상 상호배타적인게 아니라 lock을 여러 쓰레드가 획득할 수 있다는 얘기가 되는거라 모순이죠.

태상규님의 프로필 이미지
태상규

작성한 질문수

질문하기