2010-08-23 8 views
6

Para mí ahora parece que funcionalmente Semaphore.WaitOne/Release es igual a Monitor.Wait/Pulse. Saltarse las capacidades de interproceso, la velocidad (sí, se gestiona el monitor) otras diferencias no funcionales, ¿cuál es la diferencia real entonces?Semaphore.WaitOne/Release vs Monitor.Pulse/Wait

Respuesta

10

El objetivo principal de Semaphore es controlar el acceso a un conjunto finito de recursos. El hilo puede participar en la adquisición de recursos llamando al WaitOne y Release. Un thead debe llamar al WaitOne para adquirir el recurso. Sin embargo, solo se bloqueará si el conteo del semáforo llega a 0, de lo contrario, el hilo es libre de adquirirlo inmediatamente. Una vez que el hilo ha terminado, debe llamar al Release para indicarle al semáforo que se ha liberado un espacio adicional para otro hilo.

Monitor.Wait y Monitor.Pulse son drásticamente diferentes. Lo primero y más importante es que no hay conteo involucrado. Si se llama al Pulse en ausencia de cualquier llamada al Wait, la señal se ignora y se descarta. No está en cola de la misma manera que lo haría un semáforo. De hecho, el comportamiento de Wait y Pulse no tiene ningún significado inherente. El Wait simplemente está esperando un cambio en el estado del bloqueo adquirido (adquirido en Monitor.Enter). El Pulse es la señal de que algo cambió. Es por eso que a menudo se ve Wait llamado en un bucle while. El hilo de espera debe volver a probar la condición de espera porque no tiene idea de qué cambió.

Monitor.Wait y Monitor.Pulse son mecanismos de sincronización fundamentales que se pueden utilizar para formar prácticamente cualquier otro dispositivo de sincronización, incluidos semáforos.

+0

¡esta es una respuesta increíble! ¡Me quitó las cosas! – Andrey

+0

A menudo es mejor considerar 'Pulse' como una señal de que algo" puede haber "cambiado. La idea esencial es que si un método necesita esperar a que un recurso cambie de alguna manera (por ejemplo, una cola para tener datos en él), y ese cambio solo se puede realizar mediante un código que mantenga el bloqueo de ese recurso, el método anterior puede probar si el cambio ha sucedido y, si no, llamar 'Monitor.Wait' en el bloqueo. Si cada método que cambia los recursos bloqueados llama 'PulseAll', cualquiera que esté esperando un cambio se despertará y tendrá la oportunidad de ver si el cambio que estaban esperando ocurrió. – supercat

2

Monitor.Wait/Pulse le proporciona una variable de condición, que es más como un evento de reinicio automático que un semáforo (pero no exactamente). La principal diferencia es que un semáforo tiene un recuento, lo que significa que no necesita bloquear nada para asegurarse de no perder un pulso (a diferencia de Monitor.Wait).

Cuestiones relacionadas