Server/Study
[Server] AutoResetEvent
GiveZero
2023. 4. 26. 16:54
AutoResetEvent
using System;
using System.Threading.Channels;
namespace Server
{
// Event는 커널영역(운영체제)에 요청 -> 큰 비용 부담
class Lock
{
// bool <- 커널
private AutoResetEvent _available = new AutoResetEvent(true);
public void Acquire()
{
_available.WaitOne(); // 입장 시도
}
public void Release()
{
_available.Set();
}
}
class Program
{
private static int _num = 0;
private static Lock _lock = new Lock();
static void Thread1()
{
for (int i = 0; i < 10000; i++)
{
_lock.Acquire();
_num++;
_lock.Release();
}
}
static void Thread2()
{
for (int i = 0; i < 10000; i++)
{
_lock.Acquire();
_num--;
_lock.Release();
}
}
static void Main(string[] args)
{
Task t1 = new Task(Thread1);
Task t2 = new Task(Thread2);
t1.Start();
t2.Start();
Task.WaitAll(t1, t2);
Console.WriteLine(_num);
}
}
}
ManualResetEvent
WaitOne, Reset 두개의 행동으로 이루어지기 때문에 Lock 기능을 구현하기에는 적절하지않음
using System;
using System.Threading.Channels;
namespace Server
{
// Event는 커널영역(운영체제)에 요청 -> 큰 비용 부담
class Lock
{
// bool <- 커널
private ManualResetEvent _menuAvailable = new ManualResetEvent(false);
public void Acquire()
{
_menuAvailable.WaitOne();
_menuAvailable.Reset();
}
public void Release()
{
_available.Set();
}
}
class Program
{
private static int _num = 0;
private static Lock _lock = new Lock();
static void Thread1()
{
for (int i = 0; i < 10000; i++)
{
_lock.Acquire();
_num++;
_lock.Release();
}
}
static void Thread2()
{
for (int i = 0; i < 10000; i++)
{
_lock.Acquire();
_num--;
_lock.Release();
}
}
static void Main(string[] args)
{
Task t1 = new Task(Thread1);
Task t2 = new Task(Thread2);
t1.Start();
t2.Start();
Task.WaitAll(t1, t2);
Console.WriteLine(_num);
}
}
}
Mutex
using System;
using System.Threading.Channels;
namespace Server
{
// Mutex : 커널 공유 객체
// AutoReset, Manul와 다른점
// bool정보 뿐만 아니라 몇번 Lock을 걸었는지 체크(int)
// 엉뚱한 곳에서 Release에서 발생하는 것을 탐지
class Program
{
private static int _num = 0;
private static Mutex _lock = new Mutex();
static void Thread1()
{
for (int i = 0; i < 10000; i++)
{
_lock.WaitOne();
_num++;
_lock.ReleaseMutex();
}
}
static void Thread2()
{
for (int i = 0; i < 10000; i++)
{
_lock.WaitOne();
_num--;
_lock.ReleaseMutex();
}
}
static void Main(string[] args)
{
Task t1 = new Task(Thread1);
Task t2 = new Task(Thread2);
t1.Start();
t2.Start();
Task.WaitAll(t1, t2);
Console.WriteLine(_num);
}
}
}