C #의 Mutex와 Semaphore에 대한 나의 2 센트

스레드 동기화는 여러 스레드가 공유 리소스에 동시에 액세스하는 것을 방지하는 데 사용됩니다. Mutex와 Semaphore는 가장 중요한 관련 개념 중 두 가지입니다. 이 두 가지가 무엇이며 언제 사용해야하는지 이해합시다.

토론을 시작하기 전에 기본 개념을 간략히 살펴 보겠습니다. 스레드는 프로세스 내에서 가장 작은 실행 단위입니다. 기본적으로 다중 스레딩은 여러 작업을 동시에 수행하여 애플리케이션의 전체 처리량을 증가시키는 데 도움이됩니다.

Mutex는 프로세스간에 작동 할 수있는 동기화 기본 요소입니다. 즉, 프로세스 간 동기화에 사용할 수 있습니다. 반대로 세마포어는 동일한 시점에 공유 리소스에 액세스하는 스레드 수를 제한 할 수있는 것입니다. 본질적으로 Semaphore는 Mutex의보다 일반화 된 형태입니다.

세마포어는 공유 리소스에 동시에 액세스 할 수있는 스레드 수를 제한하는 데 사용됩니다. 본질적으로 특정 공유 리소스에 대한 소비자 수를 동시에 제한하는 데 사용됩니다. Semaphore를 활용하여 비 독점 잠금을 구현하고 동시성을 제한 할 수 있습니다.

Mutex는 공유 리소스에 대한 배타적 잠금에 사용됩니다. 즉, Mutex를 사용하면 상호 배타적 인 잠금을 획득 할 수 있습니다. 한 스레드는 주어진 시점에서 공유 리소스에 액세스 할 수 있습니다. 배타적 잠금은 특정 시점에서 단 하나의 스레드 만 중요 섹션에 들어갈 수 있도록 보장하는 데 사용됩니다. 중요 섹션은 데이터 구조 또는 여러 스레드가 공유하는 리소스로 정의 될 수 있지만 특정 시점에서 단 하나의 스레드 만 액세스 할 수 있습니다.

System.Threading.Mutex 클래스는 Mutex를 나타내고 System.Threading.Semaphore 클래스는 세마포 작업에 사용됩니다. Mutex 클래스의 인스턴스에서 WaitOne 메서드를 사용하여 잠그고 ReleaseMutex 메서드를 사용하여 잠금을 해제 할 수 있습니다.

Mutex mutexObject = new Mutex(false, "Demo");

if (!mutexObject.WaitOne(TimeSpan.FromSeconds(10), false))

     {

             Console.WriteLine("Quitting for now as another instance is in execution...");

               return;

     }

C #에서 Semaphore를 만들려면 Semaphore 클래스의 인스턴스를 만들어야합니다. Semaphore 인스턴스를 만들 때 두 개의 인수를 해당 인수 생성자에 전달해야합니다. 첫 번째 인수는 초기 리소스 항목 수를 나타내는 데 사용되는 반면 두 번째 인수는 최대 동시 리소스 항목 수를 지정하는 데 사용됩니다. 생성 될 새 스레드에 대해 모든 슬롯을 예약하려면이 두 매개 변수에 대해 동일한 값을 지정해야합니다. 다음 코드 조각은 C #에서 세마포어를 만드는 방법을 보여줍니다.

public static Semaphore threadPool = new Semaphore(3, 5);

위에 제공된 코드 스 니펫을 참조하십시오. 위의 문은 최대 5 개의 동시 요청을 지원할 수있는 threadPool이라는 세마포어 개체를 만듭니다. 생성자에 대한 첫 번째 매개 변수에 표시된대로 초기 카운트는 3으로 설정됩니다. 이는 현재 스레드에 2 개의 슬롯이 예약되어 있고 다른 스레드에 3 개의 슬롯이 있음을 의미합니다. 이제 코드를 작성해 봅시다!

다음 코드 조각은 System.Threading 네임 스페이스에서 사용 가능한 Thread 클래스를 사용하여 10 개의 스레드를 만들고 시작하는 방법을 보여줍니다. ThreadStart 델리게이트가 어떻게 사용되었는지 확인합니다.

for (int i = 0; i < 10; i++)

{

   Thread threadObject = new Thread(new ThreadStart(PerformSomeWork));

   threadObject.Name = "Thread Name: " + i;

   threadObject.Start();

}

다음은 PerformSomeWork 메서드의 코드입니다. 이것은 세마포어 작업을위한 코드를 실제로 포함하는 방법입니다.

private static void PerformSomeWork()

       {

           threadPool.WaitOne();

           Console.WriteLine("Thread {0} is inside the critical section...", Thread.CurrentThread.Name);

           Thread.Sleep(10000);

           threadPool.Release();

       }

위에 주어진 PerformSomeWork 메서드를 참조하십시오. WaitOne 메서드는 신호가 수신 될 때까지 현재 스레드를 차단하기 위해 Semaphore 인스턴스에서 호출됩니다. Release 메서드는 세마포어를 해제하기 위해 동일한 인스턴스에서 호출됩니다. 참조 할 수있는 전체 코드 목록은 다음과 같습니다.

class SemaphoreDemo

   {

       public static Semaphore threadPool = new Semaphore(3, 5);

       public static void Main(string[] args)

       {

           for (int i = 0; i < 10; i++)

           {

               Thread threadObject = new Thread(new ThreadStart(PerformSomeWork));

               threadObject.Name = "Thread Name: " + i;

               threadObject.Start();

           }

           Console.ReadLine();

       }

       private static void PerformSomeWork()

       {

           threadPool.WaitOne();

           Console.WriteLine("Thread {0} is inside the critical section...", Thread.CurrentThread.Name);

           Thread.Sleep(10000);

           threadPool.Release();

       }

   }