2022년 3월 7일 월요일

[c# AutoResetEvent]

 using System;

using System.Threading;
using System.Threading.Tasks;



/// <summary>
/// deadLock
///
//
/// </summary>

namespace ServerCore
{
    /// <summary>
    /// 컨텍스트 스위칭(Context Switching) 다른곳에 빙의하러갈때 드는 비용을 말함
    ///
    ///
    ///
    /// </summary>
    class Lock
    {

        /// <summary>
        /// True : 아무나 들어올 수 있는 상태
        /// False : 누구도 들어올 수 없는 상태
        /// 자동으로 문을 닫아준다
        /// </summary>
        ///
        /// bool <- 커널
        AutoResetEvent _available = new AutoResetEvent(true); //처음에 열린채로 시작할것인지 닫힌채로 시작할것인지 정함
       

        public void Acquire()
        {
            _available.WaitOne(); /// 입장 시도
            //_available.Reset(); 이게 생략되어 있다고 보면됨
        }

        public void Release()
        {
            ///bool 을 True로 켜준다
            _available.Set();/// flag =true
        }
    }

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

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

        static void Thread_2()
        {
            for (int i = 0; i < 10000; 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);
        }
    }
}



using System;
using System.Threading;
using System.Threading.Tasks;



/// <summary>
/// deadLock
///
//
/// </summary>

namespace ServerCore
{
    /// <summary>
    /// 컨텍스트 스위칭(Context Switching) 다른곳에 빙의하러갈때 드는 비용을 말함
    ///
    ///
    ///
    /// </summary>
    class Lock
    {
        /// bool <- 커널
        ManualResetEvent _available = new ManualResetEvent(false); //처음에 열린채로 시작할것인지 닫힌채로 시작할것인지 정함
       
        public void Acquire()
        {
            _available.WaitOne(); /// 입장 시도
            _available.Reset(); ///입장 후 문을 닫는 개념
            ///2개로 나누어져서 원자성이 지켜지지 않아서 실패!
            ///lock은 manualResetEvent로는 안된다
            ///
            /// 그러면 언제 사용해야하나??
            /// ex 한번에 하나만 들어가야하는 경우가 아니라면 사용가능하다.
            /// 대기하고 있다가 허가가 완료되면 전부 들어와도 될 때 사용하면된다.
        }

        public void Release()
        {
            ///bool 을 True로 켜준다
            _available.Set();/// flag =true
        }
    }

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

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

        static void Thread_2()
        {
            for (int i = 0; i < 10000; 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);
        }
    }
}

댓글 없음:

댓글 쓰기

git rejected error(feat. cherry-pick)

 문제 아무 생각 없이 pull을 받지않고 로컬에서 작업! 커밋, 푸시 진행을 해버렷다. push에선 remote와 다르니 당연히 pull을 진행해라고 하지만 로컬에서 작업한 내용을 백업하지 않고 진행하기에는 부담스럽다(로컬작업 유실 가능성) 해결하려...