단일 대기 스레드를 해제한 후에 신호를 받으면 자동으로 재설정되는 스레드 동기화 이벤트를 나타냅니다.
class Lock
{
AutoResetEvent _available = new AutoResetEvent(true);
public void Acquire()
{
_available.WaitOne();
// 입장을 시도하고, 입장하면 _availble의 값을 false로 수정
}
public void Release()
{
_available.Set();
// _available의 값을 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.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);
}
}
AutoResetEvent를 통해 lock이 해제되면 이를 기다리는 스레드에 신호를 주고 lock을 획득하도록 한다.
커널 모드에서의 context switching이 일어나므로 시간이 걸린다.
internal class Program
{
static int _num = 0;
static Mutex _lock = new Mutex();
static void Thread_1()
{
for(int i=0; i<100000; i++)
{
_lock.WaitOne();
_num++;
_lock.ReleaseMutex();
}
}
static void Thread_2()
{
for (int i = 0; i < 100000; i++)
{
_lock.WaitOne();
_num--;
_lock.ReleaseMutex();
}
}
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);
}
}
AutoResetEvent 대신 Mutex를 사용하여도 동일한 결과를 얻을 수 있다.