2011-04-08 9 views
10

언제 세마포어를 사용합니까? 나는 동시에 동일한 데이터/코드를 액세스하는 스레드의 수를 제한하고 생각할 수언제 세마포어를 사용해야합니까?

만 예 ...

다른 시나리오가있는 세마포어가 최선의 해결책이 될 것인가?

+2

관련 항목 : http://stackoverflow.com/questions/2350544/in-what-situation-do-you-use-a-semaphore-over-a-mutex-in-c –

+0

예 : http : // 스택 오버플로.//2375132/releasesemaphore-do-not-release-the-semaphore/2375370 # 2375370 –

답변

5

세마포어는 프로세스 간 신호 전달에 적합 할 수 있습니다. 다중 스레드 프로그래밍의 경우 세마포를 피해야합니다. 리소스에 독점적으로 액세스해야하는 경우 뮤텍스를 사용하십시오. 신호를 기다릴 필요가 있다면, 조건 변수를 사용하십시오.

가장 자주 언급되는 리소스 풀의 경우조차도 세마포어보다 조건 변수를 사용하여 더 간단하고 안전하게 구현할 수 있습니다. 이 사건을 살펴 봅시다. 세마포를 본래의 구현 (의사)과 같습니다

wait for semaphore to open 
take a resource out of the pool 
use the resource 
put it back to the pool 
open the semaphore for one more thread 

첫 번째 문제는 세마포어가 여러 스레드에 의해 액세스되는 풀을 보호하지 않는다는 것입니다. 따라서 다른 보호 장치가 필요합니다. 잠금 장치가되도록하십시오 :

wait for semaphore to open 
acquire the lock for the pool 
take a resource out of the pool 
release the lock 
use the resource 
acquire the lock 
put the resource back to the pool 
release the lock 
open the semaphore for one more thread 

액세스 할 때 풀이 비어 있지 않도록 추가 조치를 취해야합니다. 기술적으로는 세마포어를 우회하여 풀에 액세스 할 수 있지만 위의 수집 절차에 대한 리소스 가용성 보장이 중단됩니다. 따라서 풀은 해당 절차를 통해서만 액세스해야합니다.

지금까지는 그렇게 좋았지 만 스레드가 리소스를 수동적으로 기다리지 않으려면 어떻게해야합니까? 비 차단 자원 획득을 지원할 수 있습니까? 세마포어 자체가 비 차단 획득을 지원하면 쉽습니다. 그렇지 않으면 (예 : Windows에서) 문제가 발생합니다. 세마포어를 우회 할 수는 없습니다. 풀이 비어 있지 않은 경우에만 세마포를 통과하면 잠금 상태에서 완료되면 교착 상태가 발생할 수 있지만 잠금이 해제되자 마자 빈 상태 확인 결과는 쓸모 없게됩니다. 아마 할 수있는 일이지만 (시도하지는 않았지만) 분명히 상당한 추가 복잡성을 야기합니다.

조건 변수를 사용하면이 문제를 쉽게 해결할 수 있습니다.

acquire the lock 
while the resource pool is empty, 
    wait for condition variable to be signaled 
take a resource out of the pool 
release the lock 
use the resource 
acquire the lock 
put the resource back to the pool 
release the lock 
signal the condition variable 

그리고이 경우에는 비 블로킹 인수를 추가 할 수있는 문제가 없습니다

것은 : 당신이 볼 수있는 바와 같이

acquire the lock 
if the resource pool is not empty, 
    take a resource out of the pool 
release the lock 
if the pool was empty, return 

, 그것도 조건에 액세스 할 필요가 없다 여기 차단 인수와 의사입니다 변수를 사용하고 차단 사례에 아무런 해를 끼치 지 않습니다. 나에게 그것은 세마포어를 사용하는 것보다 분명히 우수하다.

3

연결 풀.

e.e. 20 개의 연결과 150 개의 스레드가 있습니다. 이 경우 세마포어를 사용하여 20 개의 연결에 대한 액세스를 제어 할 수 있습니다.

+0

+1 : 좋은 예제지만, 세마포어가 좋은 다른 상황이 있는지 궁금합니다. –

2

세마포어는 하나의 스레드에 의해 획득되어 다른 스레드에서 해제 될 수 있습니다. 잠금 장치는 일반적으로이를 수행 할 수 없습니다. 스레드 A가 리소스 사용을 끝내고 스레드 B에 리소스 제어권을 넘겨 줄 때 이것을 사용했습니다.이 특정 상황에서 교착 상태를 피하기 위해 명령을 제어해야했습니다.

관련 문제