C#/네트워크

[C#][서버] Lock 기초

goliot 2024. 6. 2. 18:52
반응형

Interlocked의 단점

  • 사실상 정수만 사용 가능
  • 몇백줄의 쓰레드에서 하나하나 인터락을 다 걸 수 없다.
  • 자주 사용하긴 함

Monitor

  • 동시에 여러 쓰레드가 접근하면 문제가 되는 부분
    • 임계 영역, critical section_
  • 이걸 선을 그어서 아무도 건들지 마라 라고 선언을 해보자
static int number = 0;
static object _obj = new object();  

static void Thread_1()  
{  
    for (int i = 0; i < 1000000; i++)  
    {  
        Monitor.Enter(_obj);  
        number++;  
        Monitor.Exit(_obj);  
    }  
}

static void Thread_2()  
{  
    for (int i = 0; i < 1000000; i++)  
    {  
        Monitor.Enter(_obj);  
        number--;  
        Monitor.Exit(_obj);  
    }  
}
  • 이렇게 하면 Race Condition 문제를 해결할 수 있음
  • Monitor.Enter -> 화장실 문을 잠그는 행위
    • 다른 쓰레드가 들어올 수 없음
  • Monitor.Exit -> 문을 열어주는 행위
    • 다른 쓰레드가 접근 가능
  • 이러한 상황 -> 상호배제, Mutual exclusive
    • 나만 쓸 수 있다. 나머지는 접근하지 마라
  • 즉 Interlock : 물 내리기 / Monitor : 화장실 문 잠그기

문제점

  • 코드가 엄청 길어지면 관리 어떻게 할래?
    • ex) exit 하기 전에 return을 해버린 상황 -> 문 잠가놓고 나감
    • 문이 영영 잠겨있어서 나머지 쓰레드는 대기만 계속함
      • 이런 상황을 Deadlock 이라고 함
    • 그러므로 Enter - Exit 짝을 잘 맞춰야 함
  • 만약 Exception 등으로 인해 Exit을 못한다면?
    • finally 안에 Exit을 넣기
    • 하지만 이것도 번거롭다.

해결 - lock

static void Thread_1()  
{  
    for (int i = 0; i < 1000000; i++)  
    {  
        lock (_obj)  
        {  
            number++;  
        }  
    }  
}
  • lock 키워드를 사용하면 자동으로 나갈 때 문을 열어줌
반응형

'C# > 네트워크' 카테고리의 다른 글

[c#][서버] Lock 구현 이론  (0) 2024.06.02
[c#][서버] 데드락  (0) 2024.06.02
[C#][서버] Interlocked  (0) 2024.06.01
[C#][서버] 메모리 배리어  (0) 2024.06.01
[C#][서버] 캐시 이론  (0) 2024.05.31