본문 바로가기
c#_게임서버

spinlock, autoResetEvent, ReaderWriterLock

by kcj3054 2022. 7. 2.

Spinlock

  • 스핀락은 양보하거나 비키지않고 계속 critical section 부근을 맴도는 것이다. c#에서는 spinlock이 모두 구현되어있다.
 class SpinLock
    {
        //volatile bool _locked = false;

        volatile int _locked = 0;

        public void Acquire()
        {
            //두개의 스레드가 동시에 들어가게된다면 문제가 발생하게 된다.
            // lock을 잠그고 푸는 것을 하나의 동작으로 이루어지게 해야한다. 별도의 동작이된다면 문제가 발생한다. 
            //while(_locked)
            //{
            //    // 잠김이 풀리길 원한다. 
            //}

            //_locked = true;


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

        }

        public void Release()
        {
            _locked = 0;
        }
    }
  • 위의 소스에서
  //while(_locked)
            //{
            //    // 잠김이 풀리길 원한다. 
            //}

            //_locked = true;
  • 이런 방법으로 lock을 걸고 푸는 행위가 독립적으로 이루어지면 멀티스레드 환경에서는 문제가 된다. 다른 스레드가 끼어들 수 있어서 동시에 두개이상의 스레드들이 화장실로 들어와서 문을 잠글 수도 있다...

  • 그래서 원자적으로 해결하기 위해서 InterLocked를 사용해서 체크가 가능하다 반환하는 값은 이전의 값, 그래서 변수명을 original로 했다.

  • Interlocked.Exchange가 ...

autoResetEvent

  • autoResetEvent는 커널단으로 가서 요청을 하는 것이다. 그래서 비용이 많이든다..

  • AutoResetEvent의 인자를 보면 bool값을 넣을 수 있다. 처음에 ture, false를 정해주는 것이다. signal 초기 상태 걸기.!

  • block the threads.. untile signaled를 보듯이 시그널 상태가 될 때까지 기다리는 것이다..

//커널단으로 가서 요청을 하는 것.! 
    class Lock
    {
        //bool  < - 커널.. 
        AutoResetEvent _available = new AutoResetEvent(true);  //auto는 문을 닫는 행위를 자동으로 해주는 것이다. 
        public void Acquire()
        {
            //block the threads.. untile signaled
            _available.WaitOne(); // 입장 시도 ..
           // _available.Reset(); // 문을 닫는다.
        }

        public void Release()
        {
            _available.Set(); // flag = true;..
        }
    }

ReaderWriter 락..

  • 모든 행위에서 lock을 걸어주면 성능에서 안좋다.. 그래서 read영역처럼 lock을 걸 필요가 없으면 lock을 걸지 않아도된다..
//read할 때는 따로 lock 을 걸지 않아도된다 write할 경우에만 lock을 거는 것이 reader writer lock..
        //[] [] [] [] [] 
        class Reward
        {

        }

        //RWLock Reader WriterLock
        static ReaderWriterLockSlim _lcok3 = new ReaderWriterLockSlim();

        static Reward GetRewardById(int id)
        {
            _lcok3.EnterReadLock();

            _lcok3.ExitReadLock();

            lock(_lock)
            {

            }
            return null;
        }

        static void AddReward(Reward reward)
        {
            _lcok3.EnterWriteLock();

            _lcok3.ExitWriteLock();

  • 당연히 c#은 구현이 이미 되어있다. slim이 더 최신버전. _lcok3.EnterWriteLock() 이 걸려있는 상태에서는 read를 할 수가 없다..

ReaderWriter 구현 .

  • 출처 : 루키스님의 서버강의를 통해 학습했습니다.

'c#_게임서버' 카테고리의 다른 글

서버 멀티스레드 버전  (0) 2022.07.09
mmorpg서버구조  (0) 2022.07.06
lock  (0) 2022.06.30
소켓프로그래밍  (0) 2022.06.28
멀티쓰레드  (0) 2022.06.28