[C# 서버] Event

이정석·2023년 8월 2일
0

CSharpServer

목록 보기
3/13

Event

Event는 멀티쓰레드 환경에서 쓰레드 간의 동기화나 통신을 위해 사용된다. 한 쓰레드는 다른 쓰레드에게 데이터가 처리 되었음을 알리는 Event나 정보가 준비되었다는 Event를 보낼 수 있다. 이러한 기능을 이용해 Lock에 적용할 수 있는데 Event를 공유자원이 준비되었을 때 발생시키는 것으로 준비되었음을 알릴 수 있다.

Event의 동작은 Set, Reset, Wait이 존재하는데 Set, Reset는 Event의 상태값을 변경하는데 사용되고 Wait은 Event가 발생할 때까지 기다리는데 사용된다.

  • Set: 이벤트를 활성화 상태로 바꾼다. 즉, 신호를 보낸다. 신호를 보낸다는 것은 어떤 이벤트의 신호를 기다리는 쓰레드를 깨운다는 것이다.
  • Reset: 이벤트를 비활성화 상태로 바꾼다.
  • Wait: 이벤트에 신호가 올때까지 기다린다.

C#에는 Event의 종류로는 자동 이벤트(AutoReset Event)와 수동 이벤트(ManualReset Event)가 있는데 두 Event의 차이는 Wait이후 Reset의 여부인데 자동 이벤트는 Reset을 따로 안해주어도 되고 수동 이벤트는 Reset을 따로 해주어야 한다.

이후에 나올 예제 코드는 SpinLock에서 다른 증감 예제로 Lock의 바뀐 부분만 다룬다.

1. AutoReset Event

AutoResetEvent를 이용해 Lock을 구현한 코드는 아래와 같다. Lock Class는 AutoResetEvent 객체를 기준으로 Acquire()Release()를 한다.

AutoResetEvent를 생성할 때 활성화 여부를 지정해주어야 하며 true는 활성되가 되어 있어 Wait을 호출한 쓰레드가 진행할 수 있음을 의미하고 falseWait을 호출한 쓰레드가 Event가 활성화 될때까지 기다려야 함을 나타낸다.

    class Lock
    {
        AutoResetEvent _available = new AutoResetEvent(true);

        public void Acquire()
        {
            _available.WaitOne();
        }

        public void Release()
        {
            _available.Set();
        }
    }

Event의 WaitWaitOne()으로 실행할 수 있으며 AutoReset Event의 특징은 WaitOne()에서 자동으로 Event를 비활성화 시켜준다는 것이다. 즉, 위 상황은 한 쓰레드가 WaitOne()를 통해 Lock을 얻었다면 Event는 비활성화 되어 다른 쓰레드가 동시에 Lock을 얻을 수 없음을 보장할 수 있다.

위의 코드로 main을 실행하면 _num은 0으로 출력된다.

2. ManualReset Event

ManualResetEvent는 AutoResetEvent와 거의 비슷하다. 단지, WaitOne()이후에 Reset()을 따로 해주어야 한다. ManualResetEvent로 Lock을 구현한 코드는 아래와 같다.

    class Lock
    {
        ManualResetEvent _available = new ManualResetEvent(true);

        public void Acquire()
        {
            _available.WaitOne();
            _available.Reset();
        }

        public void Release()
        {
            _available.Set();
        }
    }

하지만, 위의 코드로 구현한 Lock Class를 이용해 main함수를 실행시키면 _num은 0이 아닐때가 있다. 그 이유는 Lock을 얻는 WaitOne()Reset()을 한번에 하지 못했기 때문인데, 두 부분의 실행시간 차이가 동시에 실행되는 쓰레드 사이에서 2개 이상의 쓰레드가 Lock을 얻을 수 있기 때문이다.

이러한 문제로 인해 발생되는 상황은 SpinLock에서 다룬적이 있다.


참고문헌

  1. 배현직. 게임 서버 프로그래밍 교과서. 길벗, 2020
profile
게임 개발자가 되고 싶은 한 소?년

0개의 댓글