Ich publiczne interfejsy wyglądają podobnie. W dokumentacji stwierdza, że SemaphoreSlim to lekka alternatywa i nie używa semaforów jądra systemu Windows. Ten zasób stwierdza, że SemaphoreSlim jest znacznie szybszy. W jakich sytuacjach SemaphoreSlim ma większy sens niż Semaphore i odwrotnie?
c#
multithreading
semaphore
Michael Hedgpeth
źródło
źródło
Odpowiedzi:
Jedna różnica polega na tym,
SemaphoreSlim
że nie zezwala na nazwane semafory, które mogą być stosowane w całym systemie. Oznaczałoby to, że SemaphoreSlim nie może być używany do synchronizacji między procesami.Dokumentacja MSDN wskazuje również, że SemSlim powinno być używane, gdy „oczekuje się, że czas oczekiwania będzie bardzo krótki”. Zwykle dobrze pasowałoby to do pomysłu, że smukła wersja jest lżejsza w większości kompromisów.
źródło
Dokumentacja MSDN opisuje różnicę.
Jednym zdaniem:
źródło
SemaphoreSlim
jest zaimplementowany za pomocą SpinWait, więc jeśli będziesz na to dużo czekać, stracisz dużo czasu procesora. Co nie jest nawet dobrym pomysłem, jeśli twój proces jest jedynym procesem na komputerze.SemaphoreSlim jest oparty na SpinWait i Monitor, więc wątek, który czeka na uzyskanie blokady, wypala cykle procesora przez pewien czas w nadziei, że uzyska blokadę przed przejściem do innego wątku. Jeśli tak się nie stanie, wątki umożliwiają systemom zmianę kontekstu i ponowną próbę (przez spalenie kilku cykli procesora), gdy system operacyjny ponownie zaplanuje ten wątek. Przy długim oczekiwaniu ten wzorzec może przepalić znaczną liczbę cykli procesora. Tak więc najlepszym scenariuszem takiej implementacji jest sytuacja, gdy przez większość czasu nie ma czasu oczekiwania i możesz niemal natychmiast uzyskać blokadę.
Semafor opiera się na implementacji w jądrze systemu operacyjnego, więc za każdym razem, gdy nabywasz blokadę, spędzasz sporo cykli procesora, ale po tym wątek po prostu śpi tak długo, jak to konieczne, aby uzyskać blokadę.
źródło
Odnośnie kontrowersji dotyczących „krótkich czasów”:
Przynajmniej dokumentacja SemaphoreSlim MSDN stwierdza, że
w sekcji Uwagi. Ta sama sekcja mówi również o głównej różnicy między Semaphore i SemaphoreSlim:
źródło
[SemaphoreSlim and other locks] use busy spinning for brief periods before they put the thread into a true Wait state. When wait times are expected to be very short, spinning is far less computationally expensive than waiting, which involves an expensive kernel transition
: dotnet.github.io/docs/essentials/collections/...Spojrzałem tutaj na kod źródłowy i oto co wymyśliłem:
Zarówno Semaphore, jak i SemaphoreSlim pochodzą z WaitHandle, który wewnętrznie używa natywnego dojścia Win32. Dlatego musisz Dispose () oba. Tak więc pogląd, że Slim jest lekki, jest podejrzany.
SemaphoreSlim używa SpinWait wewnętrznie, podczas gdy Semaphore tego nie robi. To mówi mi, że w przypadkach, w których oczekuje się, że oczekiwanie będzie długie, Semaphore powinien działać lepiej przynajmniej w tym sensie, że nie zablokuje twojego procesora.
źródło