- Auto Reset Event : 문(Signal)이 자동으로 잠긴다
- Manual Reset Event : 문(Signal)이 수동으로 잠긴다
class Lock
{
AutoResetEvent _available = new AutoResetEvent(true/* 처음은 입장가능 */);
public void Acquire()
{
_available.WaitOne(); // 입장시도
// Auto : 입장이 되면 자동으로 다음 입장은 막는다
}
public void Release()
{
_available.Set();
}
}
이번엔 Manual로 구현해보자
class Lock
{
ManualResetEvent _available = new ManualResetEvent(true/* 처음은 입장가능 */);
public void Acquire()
{
_available.WaitOne(); // 입장시도
_available.Reset(); // 문을 닫는다
// 단, Wait와 Reset을 두 단계로 나누니 쓰레드 세이프 하지못함
// 그럼 이걸 왜 쓰나?
// 입장시도와 문을 닫는 행위를 별도로 해야할때 사용하면 된다.
}
public void Release()
{
_available.Set();
}
}
추가로 Mutex를 써보자
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);
}
}
해보면 SpinLock보다 훨씬느리다
EventLock처럼 커널단까지 가야해서인데
그럼 다시 EventLock
과 Mutex
는 무슨차이인가?
Mutex는 내부적으로 많은 정보를 갖고있다.
- 몇 번 락을 잡았는지
- Mutex를 락잡은 쓰레드 정보
이런 정보를 갖고있기에 일반 SpinLock보다는 훨씬느리게 된다