Их общедоступные интерфейсы кажутся похожими. В документации указано, что SemaphoreSlim является облегченной альтернативой и не использует семафоры ядра Windows. Этот ресурс утверждает, что SemaphoreSlim намного быстрее. В каких ситуациях SemaphoreSlim имеет больше смысла по сравнению с Semaphore и наоборот?
c#
multithreading
semaphore
Майкл Хеджпет
источник
источник
Ответы:
Одно отличие состоит в том,
SemaphoreSlim
что не разрешены именованные семафоры, которые могут быть общесистемными. Это означало бы, что SemaphoreSlim нельзя использовать для межпроцессной синхронизации.В документации MSDN также указано, что SemSlim следует использовать, когда «ожидается, что время ожидания будет очень коротким». Это обычно хорошо согласуется с идеей о том, что тонкая версия более легкая для большинства компромиссов.
источник
В документации MSDN описана разница.
Одним предложением:
источник
SemaphoreSlim
реализуется с использованием SpinWait, поэтому, если вы будете много ждать, вы потратите много времени процессора. Это даже не очень хорошая идея, если ваш процесс - единственный процесс на компьютере.SemaphoreSlim основан на SpinWait и Monitor, поэтому поток, ожидающий получения блокировки, в течение некоторого времени сжигает циклы ЦП в надежде получить блокировку до передачи другому потоку. Если этого не происходит, потоки позволяют системам переключать контекст и повторяют попытку (путем сжигания нескольких циклов ЦП), как только ОС снова планирует этот поток. При длительном ожидании этот шаблон может прожигать значительное количество циклов процессора. Таким образом, лучший сценарий для такой реализации - это когда большую часть времени нет времени ожидания, и вы можете почти мгновенно получить блокировку.
Семафор полагается на реализацию в ядре ОС, поэтому каждый раз, когда вы устанавливаете блокировку, вы тратите довольно много циклов ЦП, но после этого поток просто спит столько, сколько необходимо для получения блокировки.
источник
Относительно спора о «коротких временах»:
По крайней мере, в документации MSDN SemaphoreSlim указано, что
в разделе "Примечания". В том же разделе рассказывается об основных различиях между Semaphore и SemaphoreSlim:
источник
[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/…Я посмотрел на исходный код здесь , и это то , что я придумал:
И Semaphore, и SemaphoreSlim являются производными от WaitHandle, который внутренне использует собственный дескриптор Win32. Вот почему вам нужно использовать Dispose () как. Так что мнение о том, что Slim легкий, вызывает подозрение.
SemaphoreSlim внутренне использует SpinWait, а Semaphore - нет. Это говорит мне о том, что в случаях, когда ожидается долгое ожидание, Semaphore должен работать лучше, по крайней мере, в том смысле, что он не будет загромождать ваш процессор.
источник