Co to jest semafor?

349

Semafor to koncepcja programowania, która jest często używana do rozwiązywania problemów związanych z wielowątkowością. Moje pytanie do społeczności:

Co to jest semafor i jak go używasz?

bmurphy1976
źródło
14
flaga logiczna, której wartość jest oparta na tym, czy licznik liczb całkowitych osiągnął wyznaczony górny limit. Maksymalne zaciemnienie!
Sam

Odpowiedzi:

399

Pomyśl o semaforach jako bramkarzach w nocnym klubie. Istnieje specjalna liczba osób, które mogą przebywać w klubie jednocześnie. Jeśli klub jest pełny, nikt nie może wejść, ale jak tylko jedna osoba opuści inną osobę, może wejść.

Jest to po prostu sposób na ograniczenie liczby konsumentów dla określonego zasobu. Na przykład, aby ograniczyć liczbę jednoczesnych wywołań do bazy danych w aplikacji.

Oto bardzo pedagogiczny przykład w C # :-)

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace TheNightclub
{
    public class Program
    {
        public static Semaphore Bouncer { get; set; }

        public static void Main(string[] args)
        {
            // Create the semaphore with 3 slots, where 3 are available.
            Bouncer = new Semaphore(3, 3);

            // Open the nightclub.
            OpenNightclub();
        }

        public static void OpenNightclub()
        {
            for (int i = 1; i <= 50; i++)
            {
                // Let each guest enter on an own thread.
                Thread thread = new Thread(new ParameterizedThreadStart(Guest));
                thread.Start(i);
            }
        }

        public static void Guest(object args)
        {
            // Wait to enter the nightclub (a semaphore to be released).
            Console.WriteLine("Guest {0} is waiting to entering nightclub.", args);
            Bouncer.WaitOne();          

            // Do some dancing.
            Console.WriteLine("Guest {0} is doing some dancing.", args);
            Thread.Sleep(500);

            // Let one guest out (release one semaphore).
            Console.WriteLine("Guest {0} is leaving the nightclub.", args);
            Bouncer.Release(1);
        }
    }
}
Patrik Svensson
źródło
6
jeśli jest jak bramkarz w klubie nocnym, powinien wpuścić gości po kolei, ale kiedy go wypróbowałem, jest losowy. Na przykład. Gość 40 przyszedł pierwszy przed gościem 39. Czy jest coś, co moglibyśmy zrobić, aby to kontrolować?
TNA
2
@TNA: Tak, ma to związek ze sposobem, w jaki nowe wątki są uruchamiane w tym przykładzie, a nie w zakresie odpowiedzi.
Patrik Svensson
5
Analogia bramkarzy jest rzeczywiście epicka, ale co ciekawe, została już zastosowana: albahari.com/threading/part2.aspx#_Semaphore
Igor Brejc
Jakie wartości oferują semafory w systemach rozproszonych?
csandreas1
198

Artykuł Mutexes and Semaphores Demystified by Michael Barr jest doskonałym krótkim wprowadzeniem do tego, co odróżnia muteksy i semafory od tego, kiedy i kiedy powinny i nie powinny być używane. Fragment kilku kluczowych akapitów tutaj.

Kluczową kwestią jest to, że do ochrony wspólnych zasobów należy używać muteksów, a do sygnalizowania należy używać semaforów. Zasadniczo nie należy używać semaforów do ochrony wspólnych zasobów ani muteksów do sygnalizowania. Istnieją na przykład problemy z analogią bouncera pod względem używania semaforów do ochrony współdzielonych zasobów - możesz z nich korzystać w ten sposób, ale może to utrudniać zdiagnozowanie błędów.

Chociaż muteksy i semafory mają pewne podobieństwa w ich implementacji, zawsze należy ich używać inaczej.

Najczęstszą (ale jednak niepoprawną) odpowiedzią na pytanie postawione na górze jest to, że muteksy i semafory są bardzo podobne, z tą jedyną znaczącą różnicą, że semafory mogą liczyć się więcej niż jeden. Prawie wszyscy inżynierowie wydają się właściwie rozumieć, że muteks jest flagą binarną używaną do ochrony współdzielonego zasobu poprzez zapewnienie wzajemnego wykluczenia w krytycznych sekcjach kodu. Ale gdy poproszono ich o rozwinięcie sposobu korzystania z „liczącego semafora”, większość inżynierów - różniących się jedynie stopniem pewności - wyraża pewien gust podręcznika, że ​​są one wykorzystywane do ochrony kilku równoważnych zasobów.

...

W tym miejscu powstaje interesująca analogia, wykorzystująca ideę kluczy do łazienki jako ochrony wspólnych zasobów - łazienki. Jeśli sklep ma jedną łazienkę, wystarczy jeden klucz, aby chronić ten zasób i uniemożliwić korzystanie z niego wielu osobom jednocześnie.

Jeśli jest wiele łazienek, można pokusić się o ich równe wprowadzenie i zrobienie wielu kluczy - jest to podobne do niewłaściwego użycia semafora. Kiedy już zdobędziesz klucz, nie wiesz, która łazienka jest dostępna, a jeśli pójdziesz tą ścieżką, prawdopodobnie skończysz z użyciem muteksów, aby dostarczyć te informacje i upewnić się, że nie weźmiesz łazienki, która jest już zajęta. .

Semafor jest niewłaściwym narzędziem do ochrony kilku zasadniczo takich samych zasobów, ale tyle osób o nim myśli i używa go. Analogia bramkarza jest wyraźnie inna - nie ma kilku zasobów tego samego typu, zamiast tego istnieje jeden zasób, który może przyjąć wielu użytkowników jednocześnie. Przypuszczam, że w takich sytuacjach można zastosować semafor, ale rzadko zdarzają się sytuacje w świecie rzeczywistym, w których analogia faktycznie się utrzymuje - częściej występuje kilka tego samego typu, ale wciąż pojedyncze zasoby, takie jak łazienki, których nie można użyć tą drogą.

...

Prawidłowe użycie semafora służy do sygnalizowania jednego zadania do drugiego. Muteks ma być pobierany i zwalniany, zawsze w tej kolejności, przez każde zadanie korzystające z chronionego zasobu udostępnionego. Natomiast zadania wykorzystujące semafory albo sygnalizują, albo czekają, a nie oba jednocześnie. Na przykład Zadanie 1 może zawierać kod do wysłania (tj. Sygnału lub przyrostu) określonego semafora po naciśnięciu przycisku „zasilania”, a Zadanie 2, które wybudza wyświetlacz, czeka na tym samym semaforze. W tym scenariuszu jednym z zadań jest producent sygnału zdarzenia; drugi konsument.

...

Tutaj ważna jest uwaga, że ​​muteksy źle wpływają na systemy operacyjne w czasie rzeczywistym, powodując odwrócenie priorytetu w przypadku, gdy mniej ważne zadanie może zostać wykonane przed ważniejszym zadaniem z powodu współdzielenia zasobów. Krótko mówiąc, dzieje się tak, gdy zadanie o niższym priorytecie wykorzystuje muteks do pobrania zasobu A, a następnie próbuje złapać B, ale zostaje wstrzymany, ponieważ B jest niedostępny. W trakcie oczekiwania pojawia się zadanie o wyższym priorytecie, które potrzebuje A, ale jest już powiązane i przez proces, który nawet nie działa, ponieważ czeka na B. Istnieje wiele sposobów rozwiązania tego problemu, ale najczęściej jest to naprawione zmieniając mutex i menedżera zadań. Muteks jest w tych przypadkach znacznie bardziej złożony niż semafor binarny,

...

Przyczyna powszechnego współczesnego pomieszania muteksów i semaforów ma charakter historyczny, ponieważ sięga aż do wynalezienia w 1974 roku semafora (wielka litera „S” w tym artykule) autorstwa Djikstry. Przed tą datą żaden z bezpiecznych dla przerwania mechanizmów synchronizacji i sygnalizacji znanych komputerowcom nie był efektywnie skalowalny do wykorzystania przez więcej niż dwa zadania. Rewolucyjny, bezpieczny i skalowalny semafor Dijkstry został zastosowany zarówno do ochrony sekcji krytycznej, jak i sygnalizacji. I tak zaczęło się zamieszanie.

Później stało się jednak oczywiste dla twórców systemów operacyjnych, po pojawieniu się opartego na priorytetach prewencyjnego systemu RTOS (np. VRTX, ok. 1980 r.), Publikacji artykułów naukowych ustanawiających RMA i problemów spowodowanych odwróceniem priorytetu oraz publikacji na temat priorytetu protokoły dziedziczenia w 1990 r.3 okazało się, że muteksy muszą być czymś więcej niż tylko semaforami z licznikiem binarnym.

Mutex: udostępnianie zasobów

Semafor: sygnalizacja

Nie używaj jednego do drugiego bez dokładnego rozważenia skutków ubocznych.

Adam Davis
źródło
10
Spójrz na ten dokument PDF współbieżności Stanford. Spójrz na strony 8. Powyższe wyjaśnienie będzie miało więcej sensu niż ... patrz
Kris Subramanian
3
Książeczka semaforów jest cennym odczytu na temat tych zagadnień.
G. Bach,
@KrisSubramanian Dzięki za link. Ale dokument omawia semafory i nic o Mutexach. Czy masz na myśli, że współużytkowany bufor w tym przykładzie można chronić za pomocą Mutex? zamiast mieć 2 semafory puste Bufory i pełne Bufory
talekeDskobeDa
1
@Pramod True. Link nie dodaje żadnych notatek związanych z Mutex. Dodałem link, aby strona semafora stała się jasna dla czytelników SO. :) Co ciekawe, w tym przypadku bufor jest używany bez żadnych blokad, ponieważ jest dostępny sekwencyjnie i w okrągłym formacie. tzn. Writer zapisze na 0 i zasygnalizuje czytnikowi, by odczytał z 0. Jeśli czytnik nie odczyta z 0 i nie zasygnalizuje pisarzowi, pisarz zostanie zablokowany. Dlatego nie ma potrzeby używania muteksu do blokowania wspólnego zasobu. Różni się to od powyższej analogii do łazienki.
Kris Subramanian
@Kris Subramanian: niezły dokument, ale zawierają małe błędy: trzecia strona zaczyna stwierdzać, że „każdy wątek blokujący semafor powinien być ostrożny, aby go odblokować” - można je odblokować dowolnym wątkiem. Jeśli robisz to w tym samym wątku, używasz go po prostu jako „mutock brocken”. „Brocken”, ponieważ nadal można go przypadkowo odblokować z innego wątku - zdarzają się błędy - i złamać logikę. Wciąż miły doktor, pomyślał.
Rustam A.,
70

Mutex: wyłączny dostęp członka do zasobu

Semafor: dostęp n-członka do zasobu

Oznacza to, że mutex może być używany do synchronizacji dostępu do licznika, pliku, bazy danych itp.

Sempahore może robić to samo, ale obsługuje stałą liczbę jednoczesnych rozmówców. Na przykład mogę zawinąć wywołania bazy danych w semafor (3), aby moja aplikacja wielowątkowa trafiła do bazy danych z maksymalnie 3 jednoczesnymi połączeniami. Wszystkie próby zostaną zablokowane, dopóki nie otworzy się jedno z trzech miejsc. Sprawiają, że wykonywanie naiwnego dławienia jest naprawdę bardzo łatwe.

Michael Haren
źródło
20
Według Richarda W. Stevensa muteks jest w rzeczywistości binarnym semaforem, z tylko dwiema możliwymi wartościami: 0 i 1.
Qiang Xu,
19
@QiangXu w wewnętrznych systemach operacyjnych i zasadach projektowania Williama Stallingsa, semafor binarny różni się od muteksu w jeden bardzo ważny sposób i cytuję: „Kluczową różnicą między muteksem a binarnym semaforem jest to, że proces blokuje muteks musi być tym, który go odblokuje. W przeciwieństwie do tego, jeden proces może zablokować binarny semafor, a inny go odblokować. ” .
Kawa elektryczna
3
Ryzyko skomentowania nieaktualnego wątku nie jest poprawne. Jak wspomniano powyżej @AdamDavis, semafora nie należy (trzeba?) Używać do dostępu do zasobu dla n-członków - należy to nadal robić przy użyciu Mutex. Rozważ analogię łazienki w Coffeeshopie, gdy wiele osób czeka na dostęp lub w inny sposób wiele łazienek z podobnymi kluczami do łazienek. Raczej semafor powinien być używany do sygnalizowania między zadaniami.
cspider
21

Rozważ taksówkę, która może pomieścić łącznie 3 (z tyłu ) +2 (z przodu ) osób, w tym kierowcę. A zatem, semaphorepozwala tylko 5 osobom w samochodzie na raz. I mutexpozwala tylko 1 osobie na jednym siedzeniu samochodu.

Dlatego Mutexma umożliwić wyłączny dostęp do zasobu ( takiego jak wątek systemu operacyjnego ), podczas gdy a Semaphorema umożliwić dostęp dla n liczby zasobów jednocześnie.

NKumar
źródło
19

@Craig:

Semafor to sposób na zablokowanie zasobu, aby zagwarantować, że podczas wykonywania fragmentu kodu tylko ten fragment ma dostęp do tego zasobu. Dzięki temu dwa wątki nie będą jednocześnie uzyskiwać dostępu do zasobu, co może powodować problemy.

Nie jest to ograniczone tylko do jednego wątku. Semafor można skonfigurować tak, aby zezwalał na dostęp do zasobu określonej liczbie wątków.

Mats Fredriksson
źródło
7
To jest komentarz, a nie odpowiedź.
kaspersky
11
Tak, ale myślę, że napisałem to, zanim komentarze zostały dodane do Przepełnienia stosu. Albo nie, nie pamiętam. Tym razem jednak odpowiedziałem w komentarzu. :-)
Mats Fredriksson
16

Semafor może być również użyty jako ... semafor. Na przykład, jeśli masz wiele procesów kolejkujących dane do kolejki i tylko jedno zadanie zużywa dane z kolejki. Jeśli nie chcesz, aby Twoje zadanie konsumenckie stale odpytywało kolejkę w poszukiwaniu dostępnych danych, możesz użyć semafora.

W tym przypadku semafor nie jest wykorzystywany jako mechanizm wykluczający, ale jako mechanizm sygnalizacyjny. Zadanie konsumujące czeka na semaforze Zadanie produkcyjne publikuje w semaforze.

W ten sposób zadanie konsumujące jest uruchamiane tylko wtedy, gdy istnieją dane do usunięcia z kolejki

shodanex
źródło
11

Istnieją dwie podstawowe koncepcje budowy współbieżnych programów - synchronizacja i wzajemne wykluczanie. Zobaczymy, jak te dwa rodzaje zamków (semafory są bardziej rodzajem mechanizmu blokującego) pomagają nam osiągnąć synchronizację i wzajemne wykluczenie.

Semafor jest konstrukcją programistyczną, która pomaga nam osiągnąć współbieżność, realizując zarówno synchronizację, jak i wzajemne wykluczanie. Semafory są dwojakiego rodzaju, binarne i zliczające.

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: poczekaj (P) [to jak uzyskanie blokady] i zwolnij (V) [podobnie do zwolnienia blokady] - są to jedyne dwie operacje, które można wykonać na semaforze. W semaforze binarnym licznik logicznie przechodzi między 0 a 1. Można go uznać za podobny do zamka z dwiema wartościami: otwarta / zamknięta. Semafor zliczający ma wiele wartości dla zliczania.

Ważne jest, aby zrozumieć, że licznik semaforów śledzi liczbę zadań, które nie muszą być blokowane, tzn. Mogą robić postępy. Zadania blokują się i dodają się do listy semaforów tylko wtedy, gdy licznik wynosi zero. Dlatego zadanie jest dodawane do listy w procedurze P (), jeśli nie może się rozwijać, i „uwalniane” za pomocą procedury V ().

Teraz dość oczywiste jest, jak semafory binarne można wykorzystać do rozwiązania synchronizacji i wzajemnego wykluczenia - są to zasadniczo blokady.

dawny. 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że wykonać się dopiero po zakończeniu wykonywania B1. Powiedzmy, że wątek A przychodzi jako pierwszy - przechodzi do sem.P () i czeka, ponieważ licznik ma wartość 0 (zamknięty). Nadchodzi wątek B, kończy B1, a następnie uwalnia wątek A - który następnie kończy B2. Osiągamy synchronizację.

Spójrzmy teraz na wzajemne wykluczanie za pomocą binarnego semafora:

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 wykluczenie jest również dość proste - m1 i m2 nie mogą jednocześnie wejść do sekcji krytycznej. Tak więc każdy wątek używa tego samego semafora, aby zapewnić wzajemne wykluczenie dla swoich dwóch krytycznych sekcji. Czy można mieć większą współbieżność? Zależy od najważniejszych sekcji. (Pomyśl, jak inaczej można użyć semaforów, aby osiągnąć wzajemne wykluczenie. Wskazówka: czy koniecznie muszę używać tylko jednego semafora?)

Liczenie semaforów: semafor z więcej niż jedną wartością. Spójrzmy na to, co to oznacza - zamek z więcej niż jedną wartością? Tak otwarte, zamknięte i ... hmm. Jaki jest pożytek z blokady wielostopniowej we wzajemnym wykluczaniu lub synchronizacji?

Weźmy łatwiejszy z dwóch:

Synchronizacja z wykorzystaniem semafora zliczającego: Załóżmy, że masz 3 zadania - nr 1 i 2, które chcesz wykonać po 3. Jak zaprojektowałbyś swoją 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 się zamknięty, upewniasz się, że t1 i t2 blokują, dodawane są do listy semaforów. Potem pojawia się wszystkie ważne t3, kończy swój biznes i uwalnia t1 i t2. W jakiej kolejności są uwalniane? Zależy od implementacji listy semaforów. Może to być FIFO, może mieć określony priorytet itp. (Uwaga: pomyśl o tym, jak ułożysz P i V; s, jeśli chcesz, aby t1 i t2 były wykonywane w określonej kolejności i jeśli nie byłeś świadomy implementacji semafora)

(Dowiedz się: co się stanie, jeśli liczba V jest większa niż liczba P?)

Wzajemne wykluczanie Korzystanie z liczenia semaforów: Chciałbym, abyś skonstruował w tym celu swój własny pseudokod (sprawia, że ​​rozumiesz lepiej!) - ale podstawowa koncepcja jest taka: semafor liczenia licznika = N pozwala N zadań swobodnie wchodzić do sekcji krytycznej . Oznacza to, że masz N zadań (lub wątków, jeśli chcesz), wchodzisz do sekcji krytycznej, ale zadanie N + 1 zostaje zablokowane (przechodzi na naszą ulubioną listę zablokowanych zadań) i jest przepuszczane tylko wtedy, gdy ktoś V jest semaforem przynajmniej raz. Licznik semaforów zamiast wahać się między 0 a 1, teraz przechodzi między 0 i N, umożliwiając N zadaniom swobodne wchodzenie i wychodzenie, nie blokując nikogo!

O rany, dlaczego miałbyś potrzebować tak głupiej rzeczy? Czy nie chodzi o to, by wzajemne wykluczenie nie pozwalało więcej niż jednemu facetowi na dostęp do zasobów? (Wskazówka Wskazówka ... Nie zawsze masz tylko jeden dysk w komputerze, prawda ...?)

Do przemyślenia : Czy wzajemne wykluczenie osiąga się, mając sam liczący semafor? Co się stanie, jeśli masz 10 instancji zasobu, a 10 wątków wchodzi (przez semafor zliczający) i próbujesz użyć pierwszej instancji?

aspen100
źródło
7

Semafor to obiekt zawierający liczbę naturalną (tj. Liczbę całkowitą większą lub równą zero), na której zdefiniowane są dwie operacje modyfikujące. Jedna operacja Vdodaje 1 do naturalnego. Druga operacja Pzmniejsza liczbę naturalną o 1. Obie czynności są atomowe (tzn. Żadna inna operacja nie może być wykonana w tym samym czasie co a Vlub a P).

Ponieważ liczby naturalnej 0 nie można zmniejszyć, wywołanie Psemafora zawierającego 0 zablokuje wykonanie procesu wywołującego (/ wątku) do momentu, w którym liczba nie będzie już równa 0 i Pbędzie mogła zostać pomyślnie (i atomowo) wykonana.

Jak wspomniano w innych odpowiedziach, semaforów można użyć do ograniczenia dostępu do określonego zasobu do maksymalnej (ale zmiennej) liczby procesów.

Mweerden
źródło
7

Stworzyłem wizualizację, która powinna pomóc w zrozumieniu pomysłu. Semafor kontroluje dostęp do wspólnego zasobu w środowisku wielowątkowym. wprowadź opis zdjęcia tutaj

ExecutorService executor = Executors.newFixedThreadPool(7);

Semaphore semaphore = new Semaphore(4);

Runnable longRunningTask = () -> {
    boolean permit = false;
    try {
        permit = semaphore.tryAcquire(1, TimeUnit.SECONDS);
        if (permit) {
            System.out.println("Semaphore acquired");
            Thread.sleep(5);
        } else {
            System.out.println("Could not acquire semaphore");
        }
    } catch (InterruptedException e) {
        throw new IllegalStateException(e);
    } finally {
        if (permit) {
            semaphore.release();
        }
    }
};

// execute tasks
for (int j = 0; j < 10; j++) {
    executor.submit(longRunningTask);
}
executor.shutdown();

Wynik

Semaphore acquired
Semaphore acquired
Semaphore acquired
Semaphore acquired
Could not acquire semaphore
Could not acquire semaphore
Could not acquire semaphore

Przykładowy kod z artykułu

Włodzimierz
źródło
3

Flaga sprzętu lub oprogramowania. W systemach wielozadaniowych semafor jest tak zmienny, że ma wartość wskazującą status wspólnego zasobu. Proces wymagający zasobu sprawdza semafor, aby określić status zasobów, a następnie decyduje, jak postępować.

MABUTOBRIGHTON
źródło
2

Semafory działają jak ograniczniki wątków.

Przykład: Jeśli masz pulę 100 wątków i chcesz wykonać operację DB. Jeśli 100 wątków uzyskuje dostęp do DB w danym momencie, może wystąpić problem z blokowaniem w DB, więc możemy użyć semafora, który dopuszcza tylko ograniczony wątek naraz. Poniżej Przykład dopuszcza tylko jeden wątek na raz. Gdy wątek acquire()wywoła metodę, uzyska dostęp, a po wywołaniu release()metody zwolni dostęp, aby następny wątek uzyskał dostęp.

    package practice;
    import java.util.concurrent.Semaphore;

    public class SemaphoreExample {
        public static void main(String[] args) {
            Semaphore s = new Semaphore(1);
            semaphoreTask s1 = new semaphoreTask(s);
            semaphoreTask s2 = new semaphoreTask(s);
            semaphoreTask s3 = new semaphoreTask(s);
            semaphoreTask s4 = new semaphoreTask(s);
            semaphoreTask s5 = new semaphoreTask(s);
            s1.start();
            s2.start();
            s3.start();
            s4.start();
            s5.start();
        }
    }

    class semaphoreTask extends Thread {
        Semaphore s;
        public semaphoreTask(Semaphore s) {
            this.s = s;
        }
        @Override
        public void run() {
            try {
                s.acquire();
                Thread.sleep(1000);
                System.out.println(Thread.currentThread().getName()+" Going to perform some operation");
                s.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } 
    }
sumit
źródło
1

Wyobraź sobie, że wszyscy próbują iść do łazienki, a do łazienki jest tylko pewna liczba kluczy. Teraz, jeśli nie ma wystarczającej liczby kluczy, ta osoba musi poczekać. Pomyśl więc o semaforze, który reprezentuje zestaw kluczy dostępnych dla łazienek (zasobów systemowych), do których różne procesy (osoby korzystające z łazienki) mogą poprosić o dostęp.

Teraz wyobraź sobie dwa procesy próbujące iść do łazienki w tym samym czasie. To nie jest dobra sytuacja, a semafory są używane, aby temu zapobiec. Niestety semafor jest mechanizmem dobrowolnym i procesy (nasi użytkownicy w łazience) mogą go zignorować (tzn. Nawet jeśli są klucze, ktoś może po prostu otworzyć drzwi).

Istnieją również różnice między semaforami binarnymi / muteksowymi i liczącymi.

Sprawdź notatki z wykładów na stronie http://www.cs.columbia.edu/~jae/4118/lect/L05-ipc.html .

Student Columbia w klasie Jae
źródło
0

To stare pytanie, ale jednym z najciekawszych zastosowań semaforów jest blokada odczytu / zapisu i nie została wyraźnie wymieniona.

Blokady r / w działają w prosty sposób: zużywają jedno pozwolenie dla czytelnika i wszystkie pozwolenia dla pisarzy. Rzeczywiście, trywialna implementacja blokady ar / w, ale wymaga modyfikacji metadanych podczas odczytu (właściwie dwa razy), która może stać się wąskim gardłem, wciąż znacznie lepszym niż mutex lub blokada.

Inną wadą jest to, że pisarze mogą być również uruchamiani dość łatwo, chyba że semafor jest sprawiedliwy lub zapisy uzyskują zezwolenia na wiele żądań, w takim przypadku potrzebują jawnego muteksu między sobą.

Czytaj dalej :

bestsss
źródło
-3

Semafor to sposób na zablokowanie zasobu, aby zagwarantować, że podczas wykonywania fragmentu kodu tylko ten fragment ma dostęp do tego zasobu. Dzięki temu dwa wątki nie będą jednocześnie uzyskiwać dostępu do zasobu, co może powodować problemy.

Craig H.
źródło
13
brzmi jak muteks, a nie semafor
Sam