C# SemaphoreSlim


2013/02/27 - [.Net Framework] - [Threading] Semaphore(세마포어) - C#



 지난 포스트에서 소개 했던 세마포어(Seamphore) 대신에 Windows 커널 세마포어를 사용하지 않는 간단한 클래스이다. 사용목적은 세마포어와 같으며 사용방법은 다음 코드를 보자

//한번에 허용할 수 있는 최대 쓰레드 수
private static int _maximumThreads = 3;
 
/// <summary>
/// SemaphoreSlim으로 동시 쓰레드 갯수 제한 테스트
/// </summary>
[TestMethod]
public void SemaphoreSlim_TestMethod()
{
    SemaphoreSlim ss = new SemaphoreSlim(0_maximumThreads);
 
    for (int i = 0i <= 5i++)
    {
        Thread thread = new Thread(new ThreadStart(() =>
        {
            ss.Wait();
            Thread.Sleep(100);
            Debug.WriteLine("{0} 실행 됨."Thread.CurrentThread.Name);
            ss.Release();
        }));
 
        thread.Name = String.Concat("Thread "i + 1);
        thread.Start();
    }
 
 
    Thread.Sleep(300);
    ss.Release(_maximumThreads);
 
    ss.AvailableWaitHandle.WaitOne();
    Debug.WriteLine("ss.CurrentCount after ss.Wait() = {0}"ss.CurrentCount);
}

[코드1] SemaphoreSlim으로 동시 쓰레드 실행 제한


 위 코드의 자세한 사항은 바로 이전 포스트를 보면 알 수 있을 것이다.





Semaphore(세마포어)


 세마포어는 동시에 엑세스할 수 있는 쓰레드 풀을 제한합니다. 다중 쓰레드에서 하나의 자원에 접근할 때 세마포어는 허용된 Concurrent 갯수 이상은 대기 토록하고 처리가 완료가 되면 완료된 쓰레드 갯수만큼 다음 쓰레드가 실행이 되도록 할 수 있습니다. 아래 "코드1"을 보시기 바랍니다.

//세파포어 선언 private static Semaphore _resourcePool; //한번에 허용할 수 있는 최대 쓰레드 수 private static int _maximumThreads = 3; [TestMethod] public void Semaphore_TestMethod() {     //세마포어를 할당한다.     //초기 실행 가능한 쓰레드는 0     //최대 실행 가능한 쓰레드는 3     _resourcePool = new Semaphore(0_maximumThreads);     for (int i = 0i < 8i++)     {         //쓰레드 할당         Thread thread = new Thread(Worker);         thread.Name = String.Concat("Thread "i + 1);         //쓰레드 실행         thread.Start();     }     //세마포어를 통해 대기되고 있던 쓰레드가 허용됫 갯수의 쓰레드가 수행이 되도록 한다.     _resourcePool.Release(_maximumThreads);             } /// <summary> /// 비동기 임의의 작업(3초 대기) /// </summary> private static void Worker() {     //진입된 쓰레드가 대기 하도록 한다.     _resourcePool.WaitOne();     Console.WriteLine("{0} Enters"Thread.CurrentThread.Name);     Debug.WriteLine("{0} Enters"Thread.CurrentThread.Name);     Thread.Sleep(3000);     Console.WriteLine("{0} Exits"Thread.CurrentThread.Name);     Debug.WriteLine("{0} Exits"Thread.CurrentThread.Name);     //진입된 쓰레드가 완료가 되었다고 알려준다.     _resourcePool.Release(); }

[코드1] 세마포어를 통해 동시 쓰레드 실행 갯수 제한


 위 코드에서 보는 바와 같이 최대 실행 갯수(_maximumThreads)를 3으로 세팅되었고, new Semaphore(0, _maximunThreads); 로 선언하였다. 이렇게 초기 세팅이 되면 Worker()안에서 WaitOne할 때 수행되는 쓰레드는 모두 대기 상태가 된다. 그렇지만 for문 마지막에 _resourcePool.Release(_maximunThreads);를 통해서 모두 실행 가능 하도록 하여 Wowker()의 WaitOne에서 대기하고 있던 쓰레드 3개가 수행이 되는 것이다. 이 세마포어를 통해 동시성 제어를 할 수 있다.


 Semaphore class는 커널 모드 객체를 통해 동작하기 때문에 lock, Monitor, Interlocked 보다 무거운 면이 있다 그렇지만 다음에 소개하는 SemaphoreSlim을 사용하면 가볍게 같은 방식으로 수행하도록 제어할 수 있다.

+ Recent posts