C#에는 다양한 Race condition을 막기 위한 도구들이 존재한다. 예로 들면 메모리 배리어나 Interlocked가 있다.
하지만 메모리 배리어는 데드락을 막을 수 없으며, Interlocked는 정수 타입만 막아줄 수 있다는 점이다. 그리고 코드는 점점 길어지면 이런 코드들에 임계 지역을 설정해주기 힘들어진다.
그렇기 때문에 나온 물건이 바로 Monitor이다.
사용법은 다음과 같다. 먼저 오브젝트를 하나 생성한다.
object _obj = new object();
그 다음에 atomic(원자성)을 요구하는 코드 블럭이 있다면 다음과 같이 코드를 작성한다.
Monitor.Enter(_obj); // 임계지역 시작
... 코드 블럭 ...
Monitor.Exit(_obj); // 임계지역 끝
이러한 식으로 다른 코드가 얼씬도 못하게 막는 코드 타입을 바로 상호 배제(Mutual Exclusive, Mutex)라고 부른다.
하지만 Monitor도 메모리 배리어나 Interlocked보다 사용하기 편하다는 것 뿐이지(또는 멀티스레드 상에서 안정성이 높다 뿐이지) 여전히 문제는 존재한다. 다음과 같은 경우를 보자.
Monitor.Enter(_obj); // 임계지역 시작
{
... 코드블럭 ...
return;
}
Monitor.Exit(_obj); // 임계지역 끝
이런 경우는 스레드가 임계 지점에서 나오기 전에 빠져 나와버려서, 한 스레드가 이 임계 구역을 계속 잡고 있는 식이 되버린다. 즉 데드락 상황이 걸려버린 것이다. 물론 예외처리를 이용해서 해결 방법을 강구할 수 있기는 하다.
try
{
Monitor.Enter(_obj);
... 코드 블럭 ...
}
finally
{
Monitor.Exit(_obj);
}
하지만 보통 이러지 않고 더 편리하게 사용할 수 있는 lock이라는 키워드를 이용한다.
'Operating System' 카테고리의 다른 글
[OS/네트워크] 네트워크 프로그래밍 (0) | 2022.04.24 |
---|---|
[OS] CPU 스케쥴링 (0) | 2022.02.08 |
[OS] 쓰레드 (0) | 2022.01.20 |
[OS] 프로세스 간 통신 (0) | 2022.01.11 |
[OS] Process란 (0) | 2022.01.06 |