2012-06-05 10 views
21

Jaka jest różnica między zliczaniem a semaforem binarnym.Różnica między semaforami zliczającymi i binarnymi

To, co widziałem gdzieś, to to, że oba mogą kontrolować liczbę procesów, które zażądały dla zasobu. Zarówno podjęto, jak i Uwolnij stany.

Czy istnieją jakiekolwiek ograniczenia co do ilości zasobów, które semafor binarny i semafor zliczający mogą chronić?

Oba pozwalają tylko jeden proces korzystania z zasobów w czasie ...

Czy jest jakaś inna różnica? Czy wyżej wymienione właściwości są poprawne?

+0

Dobrym przykładem użycia semafora zliczającego jest to, czy chcesz kontynuować po kilku różnych zdarzeniach. Na przykład twój program uruchamia się i inicjuje 5 różnych odczytów bazy asynchronicznej i nie powinien być kontynuowany, dopóki wszystkie 5 nie zostanie ukończone. Zwiększałbyś semafor na początku każdego odczytu i natychmiast blokowałeś 'semafor == 0'. Po zakończeniu każdego odczytu zmniejsz wartość semafora. Twój start będzie kontynuowany po zakończeniu ładowania danych. –

Odpowiedz

25

W rzeczywistości oba typy są używane do synchronizowania dostępu do zasobu udostępnionego, niezależnie od tego, czy podmiot, który próbuje uzyskać dostęp, jest procesem, czy nawet wątkiem.

Różnica jest następująca:

binarne semafory są binarne, mogą mieć tylko dwie wartości; jeden do reprezentowania, że ​​proces/wątek znajduje się w sekcji krytycznej (kod dostępu do zasobu udostępnionego), a inni powinni poczekać, a druga wskazuje, że sekcja krytyczna jest wolna.

Z drugiej strony, semafory liczące przyjmują więcej niż dwie wartości, mogą mieć dowolną wartość. Maksymalna wartość X, którą pobierają, umożliwia procesowi/wątkom X równoczesny dostęp do zasobu udostępnionego.

Aby uzyskać więcej informacji, zobacz ten link.
http://www.chibios.org/dokuwiki/doku.php?id=chibios:articles:semaphores_mutexes

EDIT
Wartość maksymalna że semafor liczenie może potrwać jest liczba procesów chcesz zezwolić do sekcji krytycznej, w tym samym czasie.
Ponownie, możesz mieć przypadek, w którym chcesz wykluczyć pewne zasoby, ale wiesz, że do tego zasobu można uzyskać dostęp poprzez maksymalną liczbę procesów (powiedzmy X), więc ustawiasz semafor zliczający o wartości X.

Pozwoliłoby to procesom X na dostęp do tego zasobu w tym samym czasie; jednak proces X + 1 będzie musiał poczekać, aż jeden z procesów w sekcji krytycznej wyjdzie.

+3

Powiedziałeś, że procesy mogą korzystać z zasobu jednocześnie! Jednak semafory są używane do implementacji wzajemnego wykluczenia, które tylko jeden proces może korzystać z zasobu na raz. Mam rację, czy nie. Co oznacza maksymalna wartość semafora zliczającego? –

+3

Cóż, zliczanie semaforów umożliwia wielu procesom korzystanie z zasobów współdzielonych w tym samym czasie. Czasami chcesz pozwolić TYLKO DWIE procesy w krytycznej sekcji jednocześnie, nie więcej, nie tylko dlatego, że dwa mogą wykonywać pracę bez błędów w logice twojego programu. Nie mogę teraz podać przykładu, ale to jest podstawowy pomysł. – Fingolfin

+1

Dziękuję Ci za wyjaśnienie tego .. Jeszcze jedno pytanie. Czy semafory binarne mają możliwość jednoczesnego korzystania z zasobu przez wiele procesów. LUB mogą po prostu zezwolić na jeden proces na raz. –

8

Istnieją dwa podstawowe pojęcia dotyczące tworzenia programów współbieżnych - synchronizacja i wzajemne wykluczanie. Przekonamy się, jak te dwa rodzaje zamków (semafory są bardziej ogólnym rodzajem mechanizmu blokującego) pomagają nam osiągnąć synchronizację i wzajemne wykluczenie.

Semafor składa się z dwóch części: licznika i listy zadań oczekujących na dostęp do określonego zasobu. Semafor wykonuje dwie operacje: wait (P) [to jest jak zdobywanie zamka] i zwolnienie (V) [podobnie jak zwolnienie blokady] - są to jedyne dwie operacje, które można wykonać na semaforze. W semaforze binarnym licznik logicznie przyjmuje wartości od 0 do 1. Można go uznać za podobny do blokady z dwiema wartościami: otwórz/zamknij. Semafor zliczający ma wiele wartości do zliczenia.

Ważne jest, aby zrozumieć, że licznik semaforów śledzi liczbę zadań, które nie muszą blokować, tj. Mogą robić postępy. Zadania blokują i dodają się do listy semaforów tylko wtedy, gdy licznik jest zerowy. W związku z tym zadanie zostanie dodane do listy w procedurze P(), jeśli nie może się rozwijać i "uwalniać" przy użyciu procedury V().

Teraz jest dość oczywiste, aby zobaczyć, jak binarne semafory mogą być używane do rozwiązywania synchronizacji i wzajemnego wykluczania - są to w zasadzie zamki.

np. Synchronizacja:

thread A{ 
semaphore &s; //locks/semaphores are passed by reference! think about why this is so. 
A(semaphore &s): s(s){} //constructor 
foo(){ 
... 
s.P(); 
;// some block of code B2 
... 
} 

//thread B{ 
semaphore &s; 
B(semaphore &s): s(s){} //constructor 
foo(){ 
... 
... 
// some block of code B1 
s.V(); 
.. 
} 

main(){ 
semaphore s(0); // we start the semaphore at 0 (closed) 
A a(s); 
B b(s); 
} 

W powyższym przykładzie, B2 można tylko wykonać po B1 zakończył realizację. Powiedzmy, że wątek A przychodzi jako pierwszy - dostaje się do sem.P() i czeka, ponieważ licznik jest równy 0 (zamknięty). Wątek B pojawia się, kończy B1, a następnie uwalnia wątek A - który kończy B2. Więc osiągamy synchronizację.

Teraz przyjrzyjmy wzajemnego wykluczania z semafora binarnego:

thread mutual_ex{ 
semaphore &s; 
mutual_ex(semaphore &s): s(s){} //constructor 
foo(){ 
... 
s.P(); 
//critical section 
s.V(); 
... 
... 
s.P(); 
//critical section 
s.V(); 
... 

} 

main(){ 
semaphore s(1); 
mutual_ex m1(s); 
mutual_ex m2(s); 
} 

Wzajemne wykluczanie jest dość prosta, jak również - m1 i m2 nie może wejść do sekcji krytycznej w tym samym czasie. Zatem każdy wątek używa tego samego semafora, aby zapewnić wzajemne wykluczenie dla dwóch kluczowych sekcji. Czy możliwa jest większa współbieżność? Zależy od krytycznych sekcji. (Pomyśl o tym, jak jeszcze można użyć semaforów osiągnąć wzajemne wykluczanie .. podpowiedź: czy koniecznie trzeba tylko użyć jeden semafora?)

Liczenie semafor: Semafor z więcej niż jedną wartość. Spójrzmy na to, co to oznacza - blokada z więcej niż jedną wartością? Tak otwarty, zamknięty i ... hmm. Na czym polega wielostopniowe blokowanie we wzajemnym wykluczeniu lub synchronizacji?

Weźmy łatwiejszy z dwóch:

Synchronizacja za pomocą semafora licznikami: powiedzmy, że mają 3 zadania - # 1 i 2, które mają być wykonywane po 3. W jaki sposób zaprojektować synchronizację?

thread t1{ 
... 
s.P(); 
//block of code B1 

thread t2{ 
... 
s.P(); 
//block of code B2 

thread t3{ 
... 
//block of code B3 
s.V(); 
s.V(); 
} 

Więc jeśli semafor zaczyna zamknięty, upewnić się, że T1 i T2 blok, dodawane do listy semafora. Następnie przychodzi wszystko ważne t3, kończy swoją działalność i zwalnia t1 i t2. W jakiej kolejności są uwalniani? Zależy od implementacji listy semaforów. Może to być FIFO, może być oparty na określonym priorytecie, itp. (Uwaga: myśleć o tym, jak zorganizować swoją P i V; s gdybyś chciał t1 i t2 być wykonany w jakimś konkretnym celu, a jeśli nie byli świadomi realizacji semafora)

(Sprawdzaj: Co się stanie, jeśli liczba V jest większa niż liczba P'S)

Wzajemne wykluczanie Korzystanie licząc semafory: Chciałbym Cię do skonstruowania własnego Pseudokod dla tego (sprawia, że ​​można zrozumieć rzeczy lepiej!) - ale podstawowa koncepcja jest taka: semafor liczący licznika = N pozwala N zadaniom swobodnie wejść do sekcji krytycznej. Oznacza to, że masz N zadań (lub wątków, jeśli chcesz) wejść do sekcji krytycznej, ale zadanie N + 1 zostanie zablokowane (trafia na naszą ulubioną listę zablokowanych zadań), a tylko zostaje przepuszczone, gdy ktoś V jest semaforem przynajmniej raz. Tak więc licznik semaforów, zamiast wahać się między 0 a 1, teraz przechodzi od 0 do N, dzięki czemu N zadań może swobodnie wchodzić i wychodzić, nie blokując nikogo!

Po co ci taki dziwaczny zamek?Czy całkowite wykluczenie nie oznacza, że ​​więcej niż jeden facet ma dostęp do zasobu? Pomyśl. (Podpowiedź ... Nie zawsze mają tylko jeden napędu w komputerze, czy ty ...?)

Aby zastanowić: Czy wzajemne wykluczanie osiągnięte przez posiadające liczenia semafora sam? Co jeśli masz 10 wystąpień zasobu i 10 wątków przychodzi (przez semafor zliczający) i próbujesz użyć pierwszego wystąpienia?

+0

To wcale nie jest dziwna blokada, gdy jeden wątek blokuje się, dopóki nie ustawisz pamięci współdzielonej i zwolni semafor (np. Ustawisz ciąg do witania świata, a następnie zwolnisz semafor, to wydrukuje on wiadomość i ponownie zablokuje semafor) do odblokowania tego wątku potrzebny jest semafor, blokada uniemożliwi jego odblokowanie, ponieważ jest on związany z nitką blokującą. Z tego, co wiem, jest to podstawa wszelkiej asynchronicznej komunikacji i prawie jedyny sposób na uzyskanie funkcjonalnych języków programowania w celu uzyskania stanu poprzez utworzenie wątku/procesu, który zmienia swój stan w zależności od komunikatów, które otrzymuje. – Dmitry

0

Najbardziej podstawowa różnica między liczenia i semafora binarnego jest to, że:

  1. binarny semafor nie może obsłużyć ograniczone czekać tak jej tylko zmiennej, które posiadają wartość binarną. Zliczanie semaforów Obsługuje ograniczone oczekiwanie, ponieważ przekształciło zmienną w strukturę z Kolejką.
  2. Implementacja Strumenture Seminarium binarne: int s;

    Liczenie semaforu: Struct S { Int S; Kolejka q; }

Korzystanie semafor zliczający teraz przetwarzać raz zyskał CS (Krytyczny fragment) musi teraz czekać na drugą, aby uzyskać CS, więc nie jest to pojedynczy strave procesu. Każdy proces ma szansę na CS.

+0

dlaczego semafor binarny musi mieć int? –