class Lock
{
// ture = Lock이 풀려있는 상태
AutoResetEvent _available = new AutoResetEvent(true);
public void Acquire()
{
// Lock 시도 and 자동으로 false상태로 전환
_available.WaitOne();
}
public void Release()
{
// Event의 상태를 signal상태로 바꿈 = true로 전환
// _available.Reset() = false로 전환
_available.Set();
}
}
Event를 사용하여 Lock이 풀리면 알려주는 방법
static void Thread1()
{
for (int i = 0; i < 100000; i++)
{
_lock.Acquire();
_num++;
_lock.Release();
}
}
static void Thread2()
{
for (int i = 0; i < 100000; i++)
{
_lock.Acquire();
_num--;
_lock.Release();
}
}
단, 시간이 조금 걸려 이전처럼 10만번을 돌리면 바로 결과가 뜨지 않는다.
ManualResetEvent _available = new ManualResetEvent(true);
public void Acquire()
{
_available.WaitOne();
_available.Reset();
}
AutoResetEvent의 WaitOne()에는 Reset이 포함되어있어서 자동으로 false가 된다.
ManualResetEvent를 사용할 경우 자동으로 false 전환이 되지 않아 Reset을 해주어야하는데 이럴 경우 true인지 확인하고 false로 만드는 행위가 2단계로 실행되어 원자적이지 않아 제대로 된 결과가 나오지 않는다.
(쓰레드를 여러개 입장 시키려는 경우 사용)
Event의 경우 커널까지 가기 때문에 속도가 느림
class Program
{
static int _num = 0;
static Mutex _lock = new Mutex();
static void Thread1()
{
for (int i = 0; i < 100000; i++)
{
_lock.WaitOne();
_num++;
_lock.ReleaseMutex();
}
}
static void Thread2()
{
for (int i = 0; i < 100000; i++)
{
_lock.WaitOne();
_num--;
_lock.ReleaseMutex();
}
}
Mutex는 Event와 비슷하나 몇번 잠구었는지를 기억한다.
WaitOne()을 2번 호출했다면 ReleaseMutex()를 2번 호출해야 Lock이 풀린다.
또한 ThreadId를 가지고 있다.
WaitOne()을 한 Thread가 아닌 다른 Thread가 Release를 하려고 하면 Error
'네트워크' 카테고리의 다른 글
ReaderWriterLock 구현 (0) | 2023.08.05 |
---|---|
ReaderWriterLock (0) | 2023.08.04 |
SpinLock (0) | 2023.08.02 |
DeadLock (0) | 2023.08.01 |
Lock 기초 (0) | 2023.07.31 |