class SpinLock
{
public:
void Lock()
{
// CAS (Compare-And-Swap)
// 기대값
bool expected = false;
// 설계된 값
bool desired = true;
// CAS 의사 코드
//if (_locked == expected) {
// expected = _locked;
// _locked = desired;
// return true;
//}
//else
//{
// expected = _locked;
// return false;
//}
while (_locked.compare_exchange_strong(expected, desired) == false)
{
expected = false;
}
}
void unlock()
{
_locked.store(false);
}
private:
// atomic은 원자라는 단어에서 차용된 기능
// 더 이상 실행 단위를 쪼갤 수 없기에 실행 단위를 하나의 흐름으로 본다
// volatile 키워드는 atomic에 무조건적으로 포함되어 있는 기능이다.
atomic<bool> _locked = false;
};
int32 sum = 0;
mutex m;
SpinLock spinLock;
스핀락 코드 설명
스핀락은 멀티스레드 환경에서
공유 자원의 접근을 제어하기 위한 간단한 동기화 기법이다.
한마디로 무한 존버단이다.
일반적인 뮤텍스와 달리 스레드를 대기 상태로 만들지 않고,
반복적으로 락 획득을 시도하는 바쁜 대기(busy-waiting) 방식을 사용한다.
스핀락 구현과 atomic의 관계
위 코드는
atomic<bool> 타입의 _locked 변수를 사용하여
락의 상태를 관리하며,
Lock() 함수에서는 CAS(Compare-And-Swap) 연산을 통해
_locked 값이 false일 때 true로 변경함으로써 락을 획득한다.
즉, atomic 변수는
여러 스레드가 동시에 접근하더라도 변수의 값이 일관되게 유지되며,
이로 인해 CAS(Compare-And-Swap) 연산과 결합하여
스핀락이 안전하게 동작할 수 있게 한다.
만약 다른 스레드가 이미 락을 가지고 있다면,
compare_exchange_strong() 호출은 실패하고
expected 값을 재설정하여 반복적으로 시도하게 된다.
unlock() 함수는 _locked를 false로 설정하여 락을 해제하며,
이로 인해 다른 스레드가 락을 획득할 수 있게 되는 로직이다.
스핀락의 특징
스핀락은 임계영역이 짧고,
스레드 전환 오버헤드를 줄이고자 할 때 유용하지만,
임계영역이 길어지면 CPU 자원을 낭비할 수 있으므로
상황에 맞게 신중하게 사용하자.
'컴퓨터 프로그래밍 공부 > 네트워크 서버' 카테고리의 다른 글
쓰레드 내부코드 보는 법 (0) | 2025.03.05 |
---|---|
멀티쓰레드 개론 (0) | 2025.02.25 |
정적라이브러리를 이용한 서버 기반 만들기 (0) | 2025.02.24 |
IP(Internet Protocol) IPv4 (0) | 2025.02.04 |
IP(Internet Protocol) 열기 (1) | 2024.12.15 |