C# :: Lecture & TIPs

[C#] Semaphore 쓰레드에 대해 알아봅시다.

Semaphore

Semaphore 는 나이트클럽에 빗대어 묘사할 수 있습니다: 정원이 정해져 있으며, 경비원에 의해 관리됩니다. 정원이 차면 더 이상 사람들이 입장할 수 없으며, 바깥에 대기열이 생깁니다. 한 사람이 나갈 때마다 대기열의 앞에서 한 사람씩 들어옵니다. 생성자는 최소한 두 개의 인수를 필요로 합니다 : 현재 나이트클럽에 들어갈 수 있는 자리 수와 클럽의 총 정원 수입니다.

정원이 1 인 Semaphore 는 Mutex 나 lock 과 유사하지만, Semaphore 는 특정 Thread 의 소유 개념이 없습니다. Semaphore 에서 Release 를 호출할 수 있는 Thread 는 어느 것이든 상관없지만, Mutex 와 lock 에서는 잠금 상태로 전환된 Thread 만이 이를 해제할 수 있습니다.

이 클래스에는 기능적으로 유사한 두 가지 버전이 있습니다 : Semaphore 와 SemaphoreSlim입니다. 후자는 .NET Framework 4.0 에서 도입되었으며, Parallel Programming (병렬 프로그래밍) 의 저지연 요구를 충족하도록 최적화되었습니다. 또한 전통적인 멀티스레딩에서도 유용하며, 대기 중에 취소 토큰을 지정할 수 있습니다. 하지만 프로세스 간의 신호로는 사용할 수 없습니다.

Semaphore 는 WaitOne 또는 Release 호출 시 약 1 μs (마이크로초) 를 소요하며, SemaphoreSlim은 그보다 약 1 / 4 정도의 시간을 소요합니다.

Semaphore 는 동시성 제한에 유용할 수 있으며, 너무 많은 Thread 들이 동시에 특정 코드를 실행하지 못하도록 할 수 있습니다. 다음 예시에서는 5 개의 스레드가 1 회당 3 개까지만 들어올 수 있는 나이트클럽에 들어가려고 한다고 가정해봅니다 :

 

class TheClub // 문단속 리스트 없음!
{
  static SemaphoreSlim _sem = new SemaphoreSlim (3); // 정원은 3

  static void Main()
  {
    for (int i = 1; i <= 5; i++) new Thread (Enter).Start (i);
  }

  static void Enter (object id)
  {
    // Threads 들 입장
    Console.WriteLine (id + " wants to enter"); 
    // 경비원 _sem 이 제한
    _sem.Wait(); 
    // 한 번에 세 개의 Threads 까지만 입장을 허용
    Console.WriteLine (id + " is in!");
    // 인원 수 * 1 초 
    Thread.Sleep (1000 * (int) id); 
    // Thread 는 클럽을 빠져나가고
    Console.WriteLine (id + " is leaving"); 
    // 다시 열어준다.
    _sem.Release();
  }
}
1 wants to enter
1 is in!
2 wants to enter
2 is in!
3 wants to enter
3 is in!
4 wants to enter
5 wants to enter
1 is leaving
4 is in!
2 is leaving
5 is in!

 

만약 Sleep 이 집약적인 디스크 I/O 를 수행하고 있다면, Semaphore 는 과도한 동시 하드 드라이브 활동을 제한하여 전체 성능을 향상시킬 수 있습니다.

이름이 있는 Semaphore 는 Mutex 와 같은 방식으로 프로세스 간을 넘나들 수 있습니다.

Leave a Reply

Discover more from Dream big, Achieve more.

Subscribe now to keep reading and get access to the full archive.

Continue reading