VisualStudio/C#서버

[C#서버][개념] 임계영역와 Evnet락 (AutoResetEvent & ManualResetEvent)

usingsystem 2022. 10. 26. 16:26
728x90

AutoResetEvent 

  • 스레드가 AutoResetEvent를 기다리고 있는 동안 다른 스레드가 이 이벤트를 발생시키면, 대기 중인 하나의 스레드만 깨어납니다. 그 후, AutoResetEvent는 자동으로 리셋됩니다.
  • Set 메서드를 호출하면 한 번만 대기 중인 스레드 중 하나가 깨어나고, 이벤트는 자동으로 리셋됩니다.

커널 동기화, 톨게이트느낌, _available.WaitOne(); 아래에  _available.Reset();사용하지 않아도 자동으로 락을 닫아준다.

 class Lock
    {
        //bool <-커널
        AutoResetEvent _available = new AutoResetEvent(true);
        public void Acauire()//획득
        {
            _available.WaitOne();//락 시도 flag = false
            //_available.Reset();자동
        }
        public void Release()//반납
        {
            _available.Set();// 락해제 flag = true
        }
    }

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

        static void Thread_1()
        {
            for (int i = 0; i < 100000; i++)
            {
                _lock.Acauire();
                _num++;
                _lock.Release();
            }
        }
        static void Thread_2()
        {
            for (int i = 0; i < 100000; i++)
            {
                _lock.Acauire();
                _num--;
                _lock.Release();
            }
        }
        static void Main(string[] arg)
        {
            Task t1 = new Task(Thread_1);
            Task t2 = new Task(Thread_2);
            t1.Start();
            t2.Start();

            Task.WaitAll(t1, t2);

            Console.WriteLine(_num);
        }

ManualResetEvent

  • ManualResetEvent는 스레드가 대기 중인 동안 다른 스레드가 이 이벤트를 발생시키면, 모든 대기 중인 스레드가 깨어납니다. 그 후, ManualResetEvent가 수동으로 리셋되기 전까지 계속해서 모든 스레드가 깨어납니다.
  • Set 메서드를 호출하면 모든 대기 중인 스레드가 깨어나고, Reset 메서드를 호출하여 이벤트를 수동으로 리셋합니다.

방문느낌으로 여러 쓰레드가 접근을 할때 좋다. 자동으로 문을 닫지않는다._available.Reset() 해야 접근 막음.

  class Lock
    {
        //bool <-커널
        ManualResetEvent _available = new ManualResetEvent(false);
        public void Acauire()//획득
        {
            _available.WaitOne();//락 시도 flag = false
            _available.Reset();//문을닫는다.
        }
        public void Release()//반납
        {
            _available.Set();// 락해제 flag = true
        }
    }
728x90