Sus interfaces públicas parecen similares. los documentación indica que SemaphoreSlim es una alternativa ligera y no usa semáforos del Kernel de Windows. Este recurso afirma que SemaphoreSlim es mucho más rápido. ¿En qué situaciones el SemaphoreSlim tiene más sentido que el Semaphore y viceversa?
c#
multithreading
semaphore
Michael Hedgpeth
fuente
fuente
Respuestas:
Una diferencia es que
SemaphoreSlim
no permite semáforos con nombre, que pueden ser de todo el sistema. Esto significaría que un SemaphoreSlim no se podría utilizar para la sincronización entre procesos.La documentación de MSDN también indica que SemSlim debe utilizarse cuando "se espera que los tiempos de espera sean muy cortos". Eso generalmente encajaría bien con la idea de que la versión delgada es más liviana para la mayoría de las compensaciones.
fuente
La documentación de MSDN describe la diferencia.
En una frase:
fuente
SemaphoreSlim
se implementa usando SpinWait, por lo que si espera mucho, perderá mucho tiempo de CPU. Lo cual ni siquiera es una buena idea si su proceso es el único proceso en la computadora.SemaphoreSlim se basa en SpinWait y Monitor, por lo que el hilo que espera adquirir el bloqueo está quemando ciclos de CPU durante algún tiempo con la esperanza de adquirir el bloqueo antes de ceder a otro hilo. Si eso no sucede, los subprocesos permiten que los sistemas cambien de contexto e intentan nuevamente (quemando algunos ciclos de CPU) una vez que el sistema operativo programa ese subproceso nuevamente. Con esperas largas, este patrón puede consumir una cantidad sustancial de ciclos de CPU. Entonces, el mejor escenario para dicha implementación es cuando la mayoría de las veces no hay tiempo de espera y puede adquirir el bloqueo casi instantáneamente.
Semaphore se basa en la implementación en el kernel del sistema operativo, por lo que cada vez que adquiere el bloqueo, gasta bastantes ciclos de CPU, pero después de eso, el hilo simplemente duerme el tiempo que sea necesario para obtener el bloqueo.
fuente
Con respecto a la controversia sobre "tiempos cortos":
Al menos la documentación de SemaphoreSlim MSDN establece que
en la sección de Comentarios. La misma sección también indica la principal diferencia entre Semaphore y SemaphoreSlim:
fuente
[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/...Miré el código fuente aquí y esto es lo que se me ocurrió:
Tanto Semaphore como SemaphoreSlim se derivan de WaitHandle, que utiliza internamente el identificador nativo de Win32. Es por eso que necesita Dispose () both. Así que la idea de que Slim es ligero es sospechosa.
SemaphoreSlim usa SpinWait internamente, mientras que Semaphore no. Eso me dice que en los casos en que se espera que la espera sea larga, Semaphore debería funcionar mejor al menos en el sentido de que no ahogará su CPU.
fuente