728x90
https://docs.microsoft.com/ko-kr/dotnet/api/system.threading.monitor?view=netcore-3.1
Monitor
Interlock과 같이 공유 자원 선점의 동기화를 위해 사용된다.
Interlock의 경우 특정 쓰레드 동기화가 필요한 코드 블럭 { 임 계 구 역 }
을 동기화 할때 쓰기보다는 특정 변수의 Increment 와 Decrement를 할 때 많이 쓰인다.
코드 블럭단위의 임계구역의 진입을 제어하기 위해 Monitor와 lock 이 제공된다.
여기서 사용되는 object obj 는 세마포어에서 비유되는 자물쇠와 같은 역할이다
P() , V() ,
Semaphore(obj) RS = obj
P();
//
if (RS >0 then RS= RS-1;
else block();
//
{
임계구역
}
V()
//
RS=RS+1;
wake_up();
//
Monitor의 경우 사용 예제
static int num = 0;
static object _lock = new object();
static void Thread_1()
{
for (int i = 0; i < 100000; ++i)
{
Monitor.Enter(_lock);
num++;
Monitor.Exit(_lock);
}
}
static void Thread_2()
{
for (int i = 0; i < 100000; ++i)
{
Monitor.Enter(_lock);
num--;
Monitor.Exit(_lock);
}
}
static void Main(string[] args)
{
Thread t1 = new Thread(Thread_1);
Thread t2 = new Thread(Thread_2);
t1.Start();
t2.Start();
t1.Join();
t2.Join();
Console.WriteLine(num);
}
하지만, 만약 임계구역내에 break; 문이 있어서 Enter(_lock) 이후
Exit (wake_up) 상태로 _lock을 전이 시켜주지 못하면 데드락(교착상태) 에 빠질 위험이 생길수도 있다
다음과 같이 해결 할 수도 있지만.
try
{
Monitor.Enter(_lock);
num++;
}
finally
{
Monitor.Exit(_lock);
}
이 경우 사용의 편의성이 더 좋은 녀석이 있다.
lock
lock의 장점
1. 모니터(세마포어)와 마찬가지로 상호배제 역할 수행
2. 동기화가 이루어지지 않아 Exit 신호를 기다리며 대기큐에 교착상태의 실수를 줄일 수 있다.
3. 좀 더 보기 편하다.
static int num = 0;
static object _lock = new object();
static void Thread_1()
{
for (int i = 0; i < 100000; ++i)
{
lock(_lock)
{
num++;
}
}
}
static void Thread_2()
{
for (int i = 0; i < 100000; ++i)
{
Monitor.Enter(_lock);
num--;
Monitor.Exit(_lock);
}
}
static void Main(string[] args)
{
Thread t1 = new Thread(Thread_1);
Thread t2 = new Thread(Thread_2);
t1.Start();
t2.Start();
t1.Join();
t2.Join();
Console.WriteLine(num);
}
300x250
'Programing_Language > C#' 카테고리의 다른 글
[쓰레드 동기화] Thread [Sleep, Yield] , ContextSwitching (0) | 2020.07.21 |
---|---|
[쓰레드 동기화]스핀 락(Spin Lock) 구현 (0) | 2020.07.20 |
[쓰레드 동기화] Interlocked (공유자원과 임계구역) (0) | 2020.07.18 |
[쓰레드] TaskCreateOptions.LongRunning (0) | 2020.07.17 |
[쓰레드] 쓰레드풀(ThreadPool) (0) | 2020.07.17 |
댓글