Suas interfaces públicas parecem semelhantes. A documentação afirma que o SemaphoreSlim é uma alternativa leve e não usa semáforos do Kernel do Windows. Este recurso afirma que o SemaphoreSlim é muito mais rápido. Em que situações o SemaphoreSlim faz mais sentido do que o Semaphore e vice-versa?
c#
multithreading
semaphore
Michael Hedgpeth
fonte
fonte
Respostas:
Uma diferença é que
SemaphoreSlim
não permite semáforos nomeados, que podem ser de todo o sistema. Isso significaria que um SemaphoreSlim não poderia ser usado para sincronização entre processos.A documentação do MSDN também indica que SemSlim deve ser usado quando "espera-se que os tempos de espera sejam muito curtos". Isso geralmente se encaixaria bem com a ideia de que a versão fina é mais leve para a maioria das desvantagens.
fonte
A documentação do MSDN descreve a diferença.
Em uma frase:
fonte
SemaphoreSlim
é implementado usando SpinWait, portanto, se você esperar muito, perderá muito tempo de CPU. O que nem é uma boa ideia se o seu processo for o único no computador.SemaphoreSlim é baseado em SpinWait e Monitor, então o encadeamento que espera para adquirir o bloqueio está queimando os ciclos da CPU por algum tempo na esperança de adquirir o bloqueio antes de ceder para outro encadeamento. Se isso não acontecer, os threads permitem que os sistemas alternem o contexto e tentam novamente (queimando alguns ciclos da CPU) assim que o SO agendar esse thread novamente. Com longas esperas, esse padrão pode queimar uma quantidade substancial de ciclos da CPU. Portanto, o melhor cenário para essa implementação é quando na maioria das vezes não há tempo de espera e você pode adquirir o bloqueio quase instantaneamente.
O Semaphore depende da implementação no kernel do sistema operacional, portanto, toda vez que você adquire o bloqueio, gasta muitos ciclos de CPU, mas depois disso o thread simplesmente dorme o tempo necessário para obter o bloqueio.
fonte
Sobre a controvérsia dos "tempos curtos":
Pelo menos a documentação do SemaphoreSlim MSDN afirma que
na seção de comentários. A mesma seção também informa a principal diferença entre Semaphore e SemaphoreSlim:
fonte
[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/...Eu olhei o código-fonte aqui e é isso que eu vim:
Tanto o Semaphore quanto o SemaphoreSlim derivam de WaitHandle, que usa internamente o identificador nativo do Win32. É por isso que você precisa Dispose () ambos. Portanto, a noção de que Slim é leve é suspeita.
O SemaphoreSlim usa SpinWait internamente, enquanto o Semaphore não. Isso me diz que nos casos em que se espera que a espera seja longa, o Semaphore deve se sair melhor, pelo menos no sentido de que não sufocará sua CPU.
fonte