[c#] 세마포어-초기 카운트의 사용은 무엇입니까?

http://msdn.microsoft.com/en-us/library/system.threading.semaphoreslim.aspx

세마포어를 만들려면 초기 개수와 최대 개수를 제공해야합니다. MSDN에 따르면 초기 횟수는 다음과 같습니다.

동시에 부여 할 수있는 세마포에 대한 초기 요청 수입니다.

최대 개수는

동시에 부여 할 수있는 세마포에 대한 최대 요청 수입니다.

최대 개수는 리소스에 동시에 액세스 할 수있는 스레드의 최대 개수라는 ​​것을 알 수 있습니다. 그러나 초기 카운트의 사용은 무엇입니까?

초기 개수가 0이고 최대 개수가 2 인 세마포를 만들면 스레드 풀 스레드가 리소스에 액세스 할 수 없습니다. 초기 개수를 1로 설정하고 최대 개수를 2로 설정하면 스레드 풀 스레드 만 리소스에 액세스 할 수 있습니다. 초기 개수와 최대 개수를 모두 2 개로 설정 한 경우에만 2 개의 스레드가 동시에 리소스에 액세스 할 수 있습니다. 그래서, 나는 초기 카운트의 중요성에 대해 정말로 혼란 스럽습니까?

SemaphoreSlim semaphoreSlim = new SemaphoreSlim(0, 2); //all threadpool threads wait
SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1, 2);//only one thread has access to the resource at a time
SemaphoreSlim semaphoreSlim = new SemaphoreSlim(2, 2);//two threadpool threads can access the resource concurrently



답변

예, 초기 숫자가 0으로 설정되면 “CurrentCount”속성을 증가시키는 동안 모든 스레드가 대기합니다. Release () 또는 Release (Int32)를 사용하여 수행 할 수 있습니다.

Release (…)-세마포어 카운터를 증가시킵니다.

Wait (…)-감소합니다

초기화에서 설정 한 최대 개수보다 큰 카운터 ( “CurrentCount”속성)를 증가시킬 수 없습니다.

예를 들면 :

SemaphoreSlim^ s = gcnew SemaphoreSlim(0,2); //s->CurrentCount = 0
s->Release(2); //s->CurrentCount = 2
...

s->Wait(); //Ok. s->CurrentCount = 1
...

s->Wait(); //Ok. s->CurrentCount = 0
...

s->Wait(); //Will be blocked until any of the threads calls Release()


답변

그래서, 나는 초기 카운트의 중요성에 대해 정말로 혼란 스럽습니까?

여기서 도움이 될 수있는 한 가지 중요한 점 Wait은 세마포어 수를 Release줄이고 증가시키는 것입니다.

initialCount즉시 허용되는 리소스 액세스 수입니다. 즉, Wait세마포어가 인스턴스화 된 직후 차단하지 않고 호출 할 수있는 횟수입니다 .

maximumCount세마포어가 얻을 수있는 최대 개수입니다. 이것은 배의 개수 Release가정 던지고 예외없이 호출 될 수있는 initialCount수는 0이었다. 경우 initialCount와 같은 값으로 설정 maximumCount한 후 호출 Release세마포어는 예외가 발생합니다 인스턴스화 직후.


답변

한 번에 리소스에 액세스 할 수있는 스레드 수를 원하십니까? 초기 카운트를 그 숫자로 설정하십시오. 이 숫자가 프로그램 수명 동안 절대 증가하지 않으면 최대 개수도 해당 숫자로 설정하십시오. 이렇게하면 리소스를 해제하는 방법에 프로그래밍 오류가있는 경우 프로그램이 충돌하여 알려줍니다.

(두 개의 생성자가 있습니다. 하나는 초기 값 만 취하는 것이고 다른 하나는 추가적으로 최대 개수를 취하는 것입니다. 둘 중 적절한 것을 사용하십시오.)


답변

이런 식으로 현재 스레드가 세마포어를 만들 때 시작부터 일부 리소스를 요청할 수 있습니다.


답변

스레드가 일정 시간 동안 리소스에 액세스하지 않도록하려면 초기 카운트를 0으로 전달하고 세마포어를 생성 한 직후에 모든 스레드에 액세스 권한을 부여하려면 최대 카운트와 동일한 초기 카운트 값을 전달합니다. . 예를 들면 :

hSemaphore = CreateSemaphoreA(NULL, 0, MAX_COUNT, NULL) ;

//Do something here
//No threads can access your resource

ReleaseSemaphore(hSemaphore, MAX_COUNT, 0) ;

//All threads can access the resource now

MSDN 설명서에 인용 된대로- “ReleaseSemaphore의 또 다른 사용은 응용 프로그램의 초기화 중에 있습니다. 응용 프로그램은 초기 개수가 0 인 세마포어를 만들 수 있습니다. 이렇게하면 세마포어의 상태가 신호 없음으로 설정되고 모든 스레드가 보호 된 리소스에 액세스하는 것을 차단합니다. 초기화를 마치면 ReleaseSemaphore를 사용하여 개수를 최대 값으로 늘리고 보호 된 리소스에 대한 정상적인 액세스를 허용합니다. “


답변

세마포어는 리소스 풀을 보호하는 데 사용할 수 있습니다 . 리소스 풀을 사용 하여 데이터베이스 연결과 같이 생성 비용많이 드는 것을 재사용 합니다.

따라서 초기 수는 일부 프로세스 시작시 풀에서 사용 가능한 리소스 수를 나타냅니다. 인 initialCount코드 를 읽을 때이 리소스 풀을 만드는 데 얼마나 많은 노력을 기울이고 있는지 생각해야합니다.

나는 초기 카운트의 중요성에 대해 정말로 혼란 스럽습니까?

Initial count = Upfront cost

따라서 애플리케이션의 사용 프로필에 따라이 값은 애플리케이션 성능에 큰 영향을 미칠 수 있습니다. 단지 임의의 숫자가 아닙니다.

무엇을 만들 었는지, 만드는 데 얼마나 많은 비용이 드는지, 즉시 필요한만큼을 신중하게 생각해야합니다. 말 그대로이 매개 변수에 대한 최적의 값을 그래프로 표시 할 수 있어야하며 프로세스의 성능을 실행되는 시간에 맞게 조정할 수 있도록 구성 가능하게 만드는 것에 대해 생각해야합니다.


답변

MSDN 이 설명 섹션에서 설명 했듯이 :

initialCount가 maximumCount보다 작 으면 현재 스레드가 WaitOne (maximumCount 빼기 initialCount)을 호출 한 것과 효과가 동일합니다. 세마포어를 생성하는 스레드에 대한 항목을 예약하지 않으려면 maximumCount 및 initialCount에 동일한 수를 사용하십시오.

따라서 초기 카운트가 0이고 max가 2이면 메인 스레드가 WaitOne을 두 번 호출하여 용량에 도달하고 (이제 세마포어 카운트가 0 임) 스레드가 Semaphore에 들어갈 수 없습니다. 유사하게 초기 카운트가 1이고 최대가 2이면 WaitOnce가 한 번 호출되고 다시 용량에 도달하기 전에 하나의 스레드 만 들어갈 수 있습니다.

초기 카운트에 0이 사용되면 리소스를 획득하기위한 최대 스레드 수를 허용하기 위해 세마포어 카운트를 최대로 늘리기 위해 항상 Release (2)를 호출 할 수 있습니다.