2011-01-16 22 views
51

http://msdn.microsoft.com/en-us/library/system.threading.semaphoreslim.aspxSemafor - Jaki jest pożytek z początkowego liczenia?

Aby utworzyć semafor, muszę podać początkową liczbę i maksymalną liczbę. MSDN stwierdza, że ​​początkowa liczba jest -

Początkowa liczba wniosków o semafora, który może zostać przyznany jednocześnie.

Choć twierdzi, że maksymalna liczba to

Maksymalna liczba wniosków o semafora, który może zostać przyznany jednocześnie.

Rozumiem, że maksymalna liczba to maksymalna liczba wątków, które mogą jednocześnie uzyskać dostęp do zasobu. Ale jaki jest pożytek z początkowego liczenia?

Jeśli utworzę semafor z początkową liczbą 0 i maksymalną liczbą 2, żaden z moich wątków wątków nie będzie mógł uzyskać dostępu do zasobu. Jeśli ustawię początkową liczbę jako 1 i maksymalną liczbę jako 2, to tylko wątek puli wątków może uzyskać dostęp do zasobu. Dopiero gdy ustawię zarówno początkową liczbę, jak i maksymalną liczbę jako 2, 2 wątki będą mogły uzyskać równoczesny dostęp do zasobu. Tak więc jestem naprawdę zdezorientowany co do znaczenia początkowej liczby?

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 
+2

Dlaczego nigdy nie przyjąłeś odpowiedzi SVGreg? – john

Odpowiedz

1

W ten sposób, gdy bieżący wątek tworzy semafor, może odebrać pewne zasoby od samego początku.

+0

Masz na myśli, że gdy chcę uzyskać dostęp do zasobu przez dwa wątki robocze, powinienem zmienić początkową liczbę? – Sandbox

+0

Nie. Jest to bieżący wątek, który zgłasza liczbę. Jeśli nie chcesz, aby bieżący wątek odebrał przepustkę 0 lub używał przeciążenia z jednym parametrem. –

45

Tak, gdy początkowa liczba zostanie ustawiona na 0 - wszystkie wątki będą czekać podczas zwiększania właściwości "CurrentCount". Możesz to zrobić za pomocą Release() lub Release (Int32).

Release (...) - będzie przyrost semafora licznika

wait (...) - pomniejszy to

Nie można zwiększyć licznika ("currentCount" własność) większe niż maksimum count, które ustawiłeś podczas inicjalizacji.

Na przykład:

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() 
+1

Twój kod będzie lepiej przedstawiony w odpowiedzi niż w komentarzu. – ChrisF

+0

Dzięki. Ponieważ myślałem, jak podświetlić kod. – SVGreg

+1

LOL to chyba po raz piąty, że osiągam tę samą odpowiedź, ponieważ dokumentacja konstruktora zawsze myli mnie, które wartości ustawić. Pozdrowienia – BlueStrat

4

Ile wątków chcesz mieć dostęp do zasobu na raz? Ustaw początkową liczbę na tę liczbę. Jeśli ta liczba nigdy nie wzrośnie przez cały czas trwania programu, ustaw maksymalną liczbę na tę liczbę. W ten sposób, jeśli masz błąd w programowaniu, w jaki sposób zwolnisz zasób, twój program ulegnie awarii i powiadomi cię o tym.

(Istnieją dwa konstruktory: jeden, który trwa tylko wartość początkową, a jeden, który dodatkowo zajmuje max count Wykorzystanie w zależności co jest właściwe.).

1

Jeśli chcesz, że żaden wątek powinien uzyskać dostęp do zasobu przez jakiś czas , przekazujesz początkową liczbę jako 0, a gdy chcesz przyznać dostęp do nich wszystkich zaraz po utworzeniu semafora, przekazujesz wartość początkowej liczby równej maksymalnej liczbie. Na przykład:

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 

Cytowane w dokumentacji MSDN - "Innym zastosowaniem ReleaseSemaphore jest inicjalizacja aplikacji.Aplikacja może utworzyć semafor z początkową liczbą zera. Spowoduje to ustawienie stanu semafora jako niezarejestrowanego i zablokuje dostęp wszystkich wątków do chronionego zasobu. Gdy aplikacja zakończy inicjalizację, używa ReleaseSemaphore zwiększyć liczbę do jego maksymalnej wartości, w celu umożliwienia normalnego dostępu do chronionego zasobu.”

+0

Przepraszam, podałem ci przykład w C++, ale mogę wyjaśnić wątpliwości. – Abhineet

28

Tak, jestem naprawdę mylić o znaczeniu początkowej liczby?

ważną kwestią, która może pomóc jest to, że Wait dekrementuje semafora licznika i Release przyrosty to.

initialCount to numer zasobu dostępów, które będą mogły natychmiast. Albo, innymi słowy, jest to n umber razy Wait można wywołać bez blokowania natychmiast po utworzeniu semafora.

maximumCount to najwyższy wynik, jaki może uzyskać semafor. Jest to liczba możliwych wywołań Release bez wyrzucania wyjątku przy założeniu, że liczba: initialCount wynosiła zero. Jeśli initialCount jest ustawiona na tę samą wartość, co maximumCount, wywołanie Release natychmiast po utworzeniu instancji semafora spowoduje zgłoszenie wyjątku.

+3

Jest to pomocne! Myślałem o Semaforach wstecz, ponieważ w InitialCount jest to liczba początkowych zasobów BLOCKED, a nie liczba zasobów, które są dostępne natychmiast. Dziękuję Ci. –

+1

@PhilipTenn, zgadzam się - dokumentacja nie jest jasna pod tym względem – BlueStrat

+0

Zgadzam się, powinny one zmienić nazwę zmiennej lub zaktualizować dokumenty – IronHide

0

Jak MSDN wyjaśnia to w sekcji Uwagi:

Jeśli initialCount jest mniejsza niż maximumCount, efekt jest taki sam, jak wtedy, gdy bieżący wątek nazwał WaitOne (maximumCount minus initialCount) razy. Jeśli nie chcesz rezerwować żadnych wpisów dla wątku, który tworzy semafor, użyj tego samego numeru dla maximumCount i initialCount.

więc jeśli początkowa liczba wynosi 0 i max 2 to tak jakby WaitOne została wywołana dwukrotnie przez głównego wątku więc doszliśmy zdolności (semafor count jest teraz 0) i nie może wejść gwint semafora. Podobnie, jeśli początkowa liczba to 1, a maksymalna to 2, WaitOnce został wywołany tylko raz i tylko jeden wątek może wejść, zanim ponownie osiągniemy wydajność i tak dalej.

Jeśli do liczby początkowej użyto 0, zawsze możemy wywołać Release (2), aby zwiększyć liczbę semaforów do max, aby umożliwić maksymalną liczbę wątków do pozyskania zasobów.

Powiązane problemy