[게임서버] AutoResetEvent와 ManualResetEvent

2022. 5. 31. 17:54·공부/게임 서버
728x90

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

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

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

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

 

세 번째 상황이 바로 AutoResetEvent다. 커널 영역에 있는 관리자에게 잠금장치가 열렸을 때를 알려달라고 부탁하는 방법이다. 관리자가 잠금장치가 열렸음을 알려주면 스레드가 한 번 실행되고 하나의 스레드가 실행된 뒤에는 자동으로 문을 닫아 다른 스레드의 방해를 막아준다.

 

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

using System;

namespace ServerStudy
{
    class Lock
    {
        AutoResetEvent _availabe = new AutoResetEvent(true); 
        // true는 아무나 들어올 수 있음. false는 아무도 들어올 수 없음.

        public void Acquire()
        {
            _availabe.WaitOne(); 
            // 입장 시도. 누군가 들어왔으면 자동으로 _availabe.Reset();실행. 즉, bool = false
        }

        public void Release()
        {
            _availabe.Set(); // bool = true;
        }
    }

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

        static void Thread_1()
        {
            for (int i = 0; i < 100000; i++) // AutoResetEvent는 커널 영영으로 요청을 보내기 때문에 반복 횟수가 많아지면 속도가 급격하게 느려짐.
            {
                _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);
        }
    }
}

 

 

이와 짝꿍같은 아이로 ManualResetEvent가 있다. AutoResetEvent는 스레드가 실행되고 나서 자동으로 문을 닫아주지만 ManualResetEvent는 수동으로 문을 닫아주어야 한다. 문을 닫기 전에 있는 모든 스레드를 한 번에 실행시키는 클래스다. ManualResetEvent는 WaitOne과 Reset을 따로 실행시켜 원자성을 해치기 때문에 Lock을 구현하기에는 적절하지 않다.

대신 아주 많은 양의 패킷을 받고 그 뒤에 다른 일을 해야하는 등의 다른 작업을 할 때 더 적합하다고 할 수 있다.

 

https://www.csharpstudy.com/Threads/manualresetevent.aspx

 

ManualResetEvent - C# 프로그래밍 배우기 (Learn C# Programming)

ManualResetEvent 클래스 ManualResetEvent는 하나의 쓰레드만 통과시키고 닫는 AutoResetEvent와 달리, 한번 열리면 대기중이던 모든 쓰레드를 실행하게 하고 코드에서 수동으로 Reset()을 호출하여 문을 닫고

www.csharpstudy.com

 

728x90

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

[게임 서버] 패킷(Packet)이란?  (0) 2022.06.02
[게임 서버] 블로킹 / 논블로킹, 동기 / 비동기  (0) 2022.06.02
[게임서버] 데드락(DeadLock)이란?  (0) 2022.05.26
[게임서버] Context Switching이란? (Thread.Sleep(1), Thread.Sleep(0), Thread.Yield())  (0) 2022.05.26
[게임서버] 스핀락(Spinlock)이란?  (0) 2022.05.25
'공부/게임 서버' 카테고리의 다른 글
  • [게임 서버] 패킷(Packet)이란?
  • [게임 서버] 블로킹 / 논블로킹, 동기 / 비동기
  • [게임서버] 데드락(DeadLock)이란?
  • [게임서버] Context Switching이란? (Thread.Sleep(1), Thread.Sleep(0), Thread.Yield())
돌멩이수프
돌멩이수프
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)
  • 블로그 메뉴

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

  • 공지사항

  • 인기 글

  • 태그

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

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
돌멩이수프
[게임서버] AutoResetEvent와 ManualResetEvent
상단으로

티스토리툴바