[게임서버] 스핀락(Spinlock)이란?

2022. 5. 25. 21:38·공부/게임 서버
728x90

영화를 보다가 화장실에 가고 싶은데 다른 사람이 변기를 차지하고 안에서 잠금장치를 걸었다면 우리는 고민한다.

1. 사람이 나올 때까지 그 앞에서 계속 기다릴지

2. 잠시 자리로 돌아갔다가 나중에 다시 와서 다시 문을 두드릴지

3. 영화관 직원에게 부탁하여 화장실에 자리가 나면 나에게 알려달라고 할지

 

첫 번째 상황이 바로 스핀락(Spinlock)이다. 스핀락이란 잠금을 원하는 스레드에 잠금을 사용할 수 있을 때까지 무한 루프를 돌면서 확인·대기하는 것을 말한다.

 

 

C#으로 작성된 내용입니다.

using System;

namespace ServerStudy
{
    class SpinLock
    {
        volatile int _locked = 0; // volatile 변수는 최적화에서 제외되고 항상 메모리에 접근함

        public void Acquire()
        {
            while(true)
            {
                //int original = Interlocked.Exchange(ref _locked, 1);
                //if (original == 0)
                //    break;

                int expected = 0;
                int desired = 1;
                if (Interlocked.CompareExchange(ref _locked, desired, expected) == expected)
                    break;
            }
        }

        public void Release()
        {
            _locked = 0;
        }
    }

    class Program
    {
        static int _num = 0;
        static SpinLock _lock = new SpinLock();

        static void Thread_1()
        {
            for (int i = 0; i < 100000; i++)
            {
                _lock.Acquire();
                _num++;
                _lock.Release();
            }
        }
        static void Thread_2()
        {
            for (int i = 0; i < 100000; i++)
            {
                _lock.Acquire();
                _num--;
                _lock.Release();
            }
        }

        static void Main(string[] args)
        {
            Task t1 = new Task(Thread_1);
            Task t2 = new Task(Thread_2);

            t1.Start();
            t2.Start();

            Task.WaitAll(t1, t2);

            Console.WriteLine(_num);
        }
    }
}

성공적으로 0이 출력되는 모습을 볼 수 있다.

 

 

이때 사용한 Interlocked.CompareExchange는 두 값을 비교하여 값이 같으면 변수 값을 바꿔주는 함수다. 

Interlocked.CompareExchange(ref _locked, desired, expected)를 사용하여 설명하면, _locked의 값과 expected를 비교하여 두 값이 같으면 _locked 값을 desired로 바꿔주는 것이다. 우리는 0을 잠금이 풀린 상태, 1을 잠금이 있는 상태로 설정하였다. 무한 루프를 돌면서 _locked의 값이 0이면 (즉, 화장실에 사람이 없어 잠금이 해제된 상태면) 값을 1로 (자신이 화장실에 들어가 잠금 장치를 작동시키도록) 바꾸게 했다.

 

Interlocked.Exchange(ref _locked, 1)로도 사용할 수 있다. int original = Interlocked.Exchange(ref _locked, 1)에서 original은 _locked의 원래 값을 뜻한다.

int original = Interlocked.Exchange(ref _locked, 1);
if (original == 0)
	break;

해당 코드는 _locked의 원래 값이 0이라면 무한 루프를 멈추라는 뜻이다.

728x90

'공부 > 게임 서버' 카테고리의 다른 글

[게임서버] 데드락(DeadLock)이란?  (0) 2022.05.26
[게임서버] Context Switching이란? (Thread.Sleep(1), Thread.Sleep(0), Thread.Yield())  (0) 2022.05.26
[게임서버] 상호배제 - Monitor.Enter, Monitor.Exit  (0) 2022.05.24
[게임서버] Interlocked란?  (0) 2022.05.24
[게임서버] Temporal locality, Spatial locality  (0) 2022.05.23
'공부/게임 서버' 카테고리의 다른 글
  • [게임서버] 데드락(DeadLock)이란?
  • [게임서버] Context Switching이란? (Thread.Sleep(1), Thread.Sleep(0), Thread.Yield())
  • [게임서버] 상호배제 - Monitor.Enter, Monitor.Exit
  • [게임서버] Interlocked란?
돌멩이수프
돌멩이수프
Information technology
  • 돌멩이수프
    WHAT DOES "IT" STAND FOR?
    돌멩이수프
  • 전체
    오늘
    어제
    • 분류 전체보기 (238)
      • 언어 (73)
        • html (3)
        • css (1)
        • java (6)
        • C (26)
        • C++ (2)
        • C# (29)
      • 공부 (7)
        • Unity (43)
        • 게임 서버 (26)
        • 네트워크 (5)
        • 데이터베이스 (7)
        • EFCore (19)
        • 기타 (14)
        • Git (5)
        • 운영체제 (1)
        • 소프트웨어공학 (21)
      • 2024-여름 (12)
      • 자기 관리 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    EntityFramework
    java
    C
    유니티
    게임서버
    자바
    네트워크
    라즈베리파이
    HTML
    tcp
    C#
    Python
    EFCore
    디자인패턴
    백준
    Entityfamework
    코딩
    C언어
    unity
    coding
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
돌멩이수프
[게임서버] 스핀락(Spinlock)이란?
상단으로

티스토리툴바