Spinlock kontra Semafor

Jakie są podstawowe różnice między semaforem i spin-Lockiem?

Kiedy użyjemy semafora nad zamkiem spinowym?

Author: mrkotfw, 2008-10-12

10 answers

Spinlock i Semafor różnią się przede wszystkim czterema rzeczami:

1. Czym są
Spinlock jest jedną z możliwych implementacji blokady, a mianowicie taką, która jest zaimplementowana przez zajęte czekanie ("spinning"). SEMAFOR jest uogólnieniem zamka (lub odwrotnie, zamek jest szczególnym przypadkiem semafora). Zazwyczaj , ale niekoniecznie , spinlocki są ważne tylko w jednym procesie, podczas gdy semafory mogą być używane do synchronizacji między różnymi procesami, też.

Blokada działa w celu wzajemnego wykluczenia, tzn.jeden wątek naraz może zdobyć blokadę i przejść do "sekcji krytycznej" kodu. Zazwyczaj oznacza to kod, który modyfikuje niektóre dane współdzielone przez kilka wątków.
SEMAFOR ma licznik i pozwala na przejęcie go przez jeden lub kilka wątków, w zależności od tego, jaką wartość do niego dodasz, oraz (w niektórych implementacjach) w zależności od tego, jaka jest jego maksymalna dopuszczalna wartość.

O ile można potraktuj blokadę jako szczególny przypadek semafora o maksymalnej wartości 1.

2. Co robią
Jak wspomniano powyżej, spinlock jest zamkiem, a zatem mechanizmem wzajemnego wykluczenia (ściśle 1 do 1). Działa on poprzez wielokrotne odpytywanie i / lub modyfikowanie lokalizacji pamięci, zwykle w sposób atomowy. Oznacza to, że uzyskanie spinlocka jest" zajętą " operacją, która prawdopodobnie spala cykle procesora przez długi czas (może na zawsze!), podczas gdy skutecznie osiąga "nic".
Główne motywacją do takiego podejścia jest fakt, że przełącznik kontekstowy ma narzut równoważny wirowaniu kilkaset (a może tysiąc) razy, więc jeśli blokadę można uzyskać przez spalenie kilku cykli wirowania, może to być ogólnie bardzo wydajne. Ponadto, w przypadku aplikacji w czasie rzeczywistym może nie być dopuszczalne blokowanie i czekanie, aż scheduler wróci do nich w odległym czasie w przyszłości.

SEMAFOR natomiast albo w ogóle się nie kręci, albo kręci się tylko przez bardzo krótki czas (jako Optymalizacja, aby uniknąć napowietrzania syscall). Jeśli SEMAFOR nie może zostać zdobyty, blokuje się, poświęcając czas procesora na inny wątek, który jest gotowy do uruchomienia. Może to oczywiście oznaczać, że kilka milisekund minie, zanim wątek zostanie ponownie zaplanowany, ale jeśli nie jest to problemem (zazwyczaj nie jest), może to być bardzo wydajne, konserwatywne podejście do procesora.

3. Jak zachowują się w obecności zatorów
Jest to powszechne błędne przekonanie, że spinlocks lub lock-free algorytmy są "na ogół szybsze" lub są przydatne tylko w przypadku " bardzo krótkich zadań "(najlepiej, aby żaden obiekt synchronizacji nie był utrzymywany dłużej niż jest to absolutnie konieczne, kiedykolwiek).
Jedną ważną różnicą jest to, jak różne podejścia zachowują się w obecności zatorów .

Dobrze zaprojektowany system zwykle ma niskie lub brak zatorów (oznacza to, że nie wszystkie wątki próbują uzyskać blokadę w tym samym czasie). Na przykład, normalnie nie pisać kod w ten sposób uzyskuje się blokadę, a następnie ładuje z sieci pół megabajta skompresowanych danych zip, dekoduje i przetwarza dane, a na koniec modyfikuje współdzielone odniesienie (dołącza dane do kontenera itp.) przed zwolnieniem zamka. Zamiast tego, blokadę można nabyć tylko w celu uzyskania dostępu do współdzielonego zasobu .
Ponieważ oznacza to, że jest znacznie więcej pracy poza sekcją krytyczną niż wewnątrz niej, oczywiście prawdopodobieństwo, że wątek znajduje się wewnątrz sekcji krytycznej jest stosunkowo niska, a więc kilka wątków walczy o blokadę w tym samym czasie. Oczywiście co jakiś czas dwa wątki będą próbowały zdobyć blokadę w tym samym czasie (jeśli to nie mogłoby się zdarzyć, nie potrzebowałbyś blokady!), ale jest to raczej wyjątek niż reguła w" zdrowym " systemie.

W takim przypadku spinlock znacznie przewyższa SEMAFOR, ponieważ jeśli nie ma zatorów blokujących, koszt uzyskania spinlocka wynosi zaledwie kilkanaście cykli jako w porównaniu do setek / tysięcy cykli dla przełącznika kontekstowego lub 10-20 milionów cykli dla utraty pozostałej części plasterka czasu.

Z drugiej strony, ze względu na duże zatory, lub jeśli zamek jest utrzymywany przez dłuższy czas (czasami po prostu nie możesz nic na to poradzić!), spinlock spali szaloną ilość cykli procesora, aby nic nie osiągnąć.
SEMAFOR (lub mutex) jest znacznie lepszym wyborem w tym przypadku, ponieważ pozwala innemu wątkowi wykonywać użyteczne zadania w tym czasie. Lub, jeśli nie inny wątek ma coś przydatnego do zrobienia, pozwala systemowi operacyjnemu Dławić procesor i zmniejszyć ciepło / oszczędzać energię.

Również, w systemie jednordzeniowym, spinlock będzie dość nieefektywny w obecności zatorów blokujących, ponieważ wirujący wątek będzie marnował swój całkowity czas czekając na zmianę stanu, która nie może się wydarzyć (nie dopóki wątek zwalniający nie zostanie zaplanowany, co nie dzieje się podczas gdy wątek oczekujący jest uruchomiony!). Dlatego biorąc pod uwagę dowolny ilość niezgody, uzyskanie blokady zajmuje w najlepszym przypadku około 1 1/2 czasu (zakładając, że wątek zwalniający jest kolejnym zaplanowanym), co nie jest zbyt dobrym zachowaniem.

4. Jak są realizowane
SEMAFOR zazwyczaj zawija sys_futex pod Linuksem (opcjonalnie z blokadą spinową, która kończy się po kilku próbach).
Spinlock jest zwykle realizowany przy użyciu operacji atomowych i bez użycia czegokolwiek dostarczonego przez system operacyjny. W w przeszłości oznaczało to używanie zarówno instrukcji kompilatora, jak i instrukcji asemblera. Tymczasem zarówno C++11, jak i C11 mają operacje atomowe jako część języka, więc oprócz ogólnej trudności w pisaniu sprawdzalnie poprawnego kodu bez blokady, możliwe jest teraz zaimplementowanie kodu bez blokady w całkowicie przenośny i (prawie) bezbolesny sposób.

 106
Author: Damon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-21 10:14:31

W bardzo prosty sposób SEMAFOR to" ulegający "obiekt synchronizacji, spinlock to "busywait". (semafory synchronizują kilka wątków, w przeciwieństwie do mutex, guard, monitor lub sekcji krytycznej, która chroni region kodu przed pojedynczym wątkiem)

Używałbyś semafora w innych okolicznościach, ale używaj spinlocka, w którym masz zamiar zablokować na bardzo krótki czas - blokowanie jest kosztowne, zwłaszcza jeśli blokujesz dużo. W takich przypadkach może być bardziej wydajny spinlock na chwilę czekając na odblokowanie chronionego zasobu. Oczywiście jest hit wydajności, jeśli kręcisz zbyt długo.

Zazwyczaj jeśli kręcisz dłużej niż kwant wątku, to powinieneś użyć semafora.

 70
Author: gbjbaanb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-12 19:06:02

Poza tym, co powiedzieli Yoav Aviram i gbjbaanb, innym kluczowym punktem było to, że nigdy nie używasz spin-Locka na maszynie z pojedynczym procesorem, podczas gdy SEMAFOR miałby sens na takiej maszynie. W dzisiejszych czasach często trudno jest znaleźć maszynę bez wielu rdzeni, hyperthreading lub równoważną, ale w sytuacji, gdy masz tylko jeden procesor, powinieneś używać semaforów. (Ufam, że powód jest oczywisty. Jeśli pojedynczy procesor jest zajęty czekaniem na coś innego aby zwolnić blokadę spin-lock, ale działa na jedynym CPU, jest mało prawdopodobne, aby blokada została zwolniona, dopóki bieżący proces lub wątek nie zostanie uprzedzony przez O/s, co może chwilę potrwać i nic użytecznego nie dzieje się, dopóki nie nastąpi uprzedzenie.)

 25
Author: Jonathan Leffler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-26 00:53:10

From Linux Device Drivers by Rubinni

W przeciwieństwie do semaforów, spinlocki mogą być używane w kodzie, który nie może spać, takie jak obsługa przerwań

 18
Author: Zbyszek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-17 04:23:43

Nie jestem ekspertem od kernela, ale oto kilka punktów:

Nawet maszyna uniprocesorowa może używać spin-lock ' ów, jeśli preemption jądra jest włączone podczas kompilacji jądra. Jeśli preemption jądra jest wyłączony, to spin-lock (być może) rozszerza się do instrukcji void.

Ponadto, kiedy próbujemy porównać Semafor z Spin-Lockiem, wierzę, że SEMAFOR odnosi się do tego, który jest używany w jądrze, a nie do tego, który jest używany w IPC (userland).

Zasadniczo stosuje się spin-lock, jeśli krytyczne sekcja jest mała (mniejsza niż narzut snu/przebudzenia), a sekcja krytyczna nie wywołuje niczego, co może zasnąć! SEMAFOR jest używany, jeśli sekcja krytyczna jest większa i może zasnąć.

Raman Chalotra.

 8
Author: Raman Chalotra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-24 09:07:12

Spinlock odnosi się do implementacji blokowania między gwintami za pomocą instrukcji montażu zależnych od Maszyny (takich jak test-and-set). Nazywa się to spinlockiem, ponieważ wątek po prostu czeka w pętli ("spins") wielokrotnie sprawdzając, aż blokada stanie się dostępna (busy wait). Spinlocki są używane jako substytut muteksów, które są obiektami dostarczanymi przez systemy operacyjne (nie CPU), ponieważ spinlocki działają lepiej, jeśli są zablokowane przez krótki okres czasu.

Semafor jest obiekt dostarczany przez systemy operacyjne dla IPC, dlatego jego głównym celem jest komunikacja między procesami. Jako obiekt dostarczany przez system operacyjny jego wydajność nie będzie tak dobra, jak spinlock do blokowania między-thead (chociaż możliwe). Semafory są lepsze do blokowania przez dłuższy czas.

To powiedziawszy - wdrażanie splinlocków w montażu jest trudne i nie Przenośne.

 7
Author: yoav.aviram,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-12 20:49:58

Chciałbym dodać moje spostrzeżenia, bardziej ogólne i niezbyt specyficzne dla Linuksa.

W zależności od architektury pamięci i możliwości procesora, do zaimplementowania semafora w systemie wielordzeniowym lub wieloprocesorowym może być potrzebna blokada spinowa, ponieważ w takich systemach może wystąpić stan wyścigu, gdy dwa lub więcej wątków/procesów chce zdobyć SEMAFOR.

Tak, jeśli architektura pamięci oferuje blokowanie sekcji pamięci przez jeden rdzeń / procesor opóźniając wszystkie inne dostępy, a jeśli procesory oferują test-and-set, można zaimplementować SEMAFOR bez spin-Locka (ale bardzo ostrożnie!).

Jednak, ponieważ projektowane są proste/tanie systemy wielordzeniowe( pracuję w systemach wbudowanych), nie wszystkie architektury pamięci obsługują takie funkcje wielordzeniowe/wieloprocesorowe, tylko test-and-set lub równoważne. Wtedy implementacja może wyglądać następująco:

  • nabyć spin-lock (busy waiting)
  • [[9]}spróbuj zdobyć SEMAFOR
  • zwolnij spin-lock
  • jeśli SEMAFOR nie został pomyślnie przejęty, Wstrzymaj bieżący wątek do czasu zwolnienia semafora; w przeciwnym razie Kontynuuj sekcję krytyczną

Zwolnienie semafora musi być zaimplementowane w następujący sposób:

  • nabyć spin-lock
  • uwolnij SEMAFOR
  • zwolnij spin-lock

Tak, a dla prostych semaforów binarnych na poziomie systemu operacyjnego możliwe byłoby użycie tylko spin-lock jako zamiennik. Ale tylko wtedy, gdy sekcje kodu, które mają być chronione, są naprawdę bardzo małe.

Jak wspomniano wcześniej, jeśli i kiedy wdrożyć własny system operacyjny, upewnij się, aby być ostrożnym. Debugowanie takich błędów jest zabawne (moim zdaniem, nie podzielane przez wielu), ale przede wszystkim bardzo żmudne i trudne.

 6
Author: Johan Bezem,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-15 10:02:05

"mutex "(lub" mutual exclusion lock") jest sygnałem, którego dwa lub więcej procesów asynchronicznych może użyć do zarezerwowania współdzielonego zasobu do wyłącznego użytku. Pierwszy proces, który uzyska własność "mutex", również uzyska własność współdzielonego zasobu. Inne procesy muszą poczekać, aż pierwszy proces zwolni własność "mutex", zanim spróbują go uzyskać.

Najczęstszym blokowaniem w jądrze jest spinlock. Spinlock jest bardzo prosty blokada Pojedynczego Uchwytu. Jeśli proces spróbuje zdobyć spinlock i jest on niedostępny, proces będzie próbował (spinning), dopóki nie będzie mógł zdobyć blokady. Ta prostota tworzy mały i szybki zamek.

 1
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-21 07:18:03

Spinlock jest używany wtedy i tylko wtedy, gdy jesteś prawie pewien, że oczekiwany wynik nastąpi bardzo krótko, przed upływem czasu wykonania wątku.

Przykład: w module sterownika urządzenia Sterownik zapisuje "0" w rejestrze sprzętowym R0 i teraz musi poczekać, aż ten rejestr R0 stanie się 1. H / W odczytuje R0 i wykonuje jakąś pracę i zapisuje " 1 " w R0. Jest to na ogół szybkie (w mikro sekundach). Teraz wirowanie jest znacznie lepsze niż pójście spać i przerywane przez H / W. Z oczywiście podczas wirowania należy zadbać o stan awarii H/W!

Nie ma absolutnie żadnego powodu, aby aplikacja użytkownika kręciła. To nie ma sensu. Masz zamiar spin dla jakiegoś zdarzenia się zdarzyć i że zdarzenie musi być zakończone przez inną aplikację poziomu użytkownika, która nigdy nie jest gwarantowana, aby się zdarzyć w krótkim czasie. Tak więc, nie będę kręcić w ogóle w trybie użytkownika. Lepiej sleep () lub mutexlock () lub SEMAFOR lock () w trybie użytkownika.

 1
Author: CancerSoftware,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-21 05:59:03

Od Jaka jest różnica między zamkami spinowymi a semaforami? by Maciej Piechotka:

Obie zarządzają ograniczonym zasobem. Najpierw opiszę różnicę między semaforem binarnym (mutex) a spin Lockiem.

Spin locks wykonuje ruchliwe oczekiwanie - tzn. utrzymuje pętlę uruchomioną:

while (try_acquire_resource ()); 
 ...  
release();

Wykonuje bardzo lekkie Blokowanie/odblokowywanie, ale jeśli gwint blokujący zostanie uprzedzony przez inne, które spróbują uzyskać dostęp do tego samego resouce drugi po prostu spróbuje uniewinnić zasób, dopóki nie wyczerpie się quanta procesora.
Z drugiej strony mutex zachowuje się bardziej jak:

if (!try_lock()) {
    add_to_waiting_queue ();
    wait();
}
...
process *p = get_next_process_from_waiting_queue ();
p->wakeUp ();

Dlatego jeśli wątek będzie próbował zdobyć zablokowany zasób, zostanie on zawieszony, dopóki nie będzie dostępny dla niego. Blokowanie / odblokowywanie jest znacznie cięższe, ale oczekiwanie jest "bezpłatne" i "uczciwe".

Semafor {[5] } jest blokadą, która może być używana wielokrotnie (znana z inicjalizacji) - na przykład 3 wątki są pozwala na symulację posiadania zasobu, ale nie więcej. Jest używany np. w problemach producenta/konsumenta lub ogólnie w kolejkach:

P(resources_sem)
resource = resources.pop()
...
resources.push(resources)
V(resources_sem)

Różnica między semaforem, mutexem i spinlockiem?

Blokowanie w Linuksie

 1
Author: vinayak jadi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-13 12:36:24