2011-04-08 37 views
10

¿Cuándo se usarían semáforos?¿Cuándo debería usar semáforos?

único ejemplo que se me ocurre es limitar el número de hilos que acceden a los mismos datos/código de forma simultánea ...

Cualesquiera otros escenarios en los que los semáforos sería la mejor solución?

+2

Relacionados: http://stackoverflow.com/questions/2350544/in-what-situation-do-you-use-a-semaphore-over-a-mutex-in-c –

+0

Un ejemplo: http: // desbordamiento de pila.com/questions/2375132/releasesemaphore-does-not-release-the-semáforo/2375370 # 2375370 –

Respuesta

5

Los semáforos pueden ser apropiados para la señalización entre procesos. Para la programación multiproceso, se deben evitar semáforos. Si necesita acceso exclusivo a un recurso, use mutex. Si necesita esperar una señal, use la variable de condición.

Incluso el caso más mencionado de un grupo de recursos se puede implementar de manera más simple y segura con una variable de condición que con un semáforo. Miremos este caso. Una implementación ingenua con un semáforo se vería así (pseudocódigo):

wait for semaphore to open 
take a resource out of the pool 
use the resource 
put it back to the pool 
open the semaphore for one more thread 

El primer problema es que el semáforo no protege la piscina contra el acceso de varios hilos. Entonces, se requiere otra protección. Que sea una cerradura: deben tomarse para asegurar la piscina

wait for semaphore to open 
acquire the lock for the pool 
take a resource out of the pool 
release the lock 
use the resource 
acquire the lock 
put the resource back to the pool 
release the lock 
open the semaphore for one more thread 

medidas adicionales no está vacío cuando se accede. Técnicamente, es posible acceder al grupo evitando el semáforo, pero se romperían las garantías de disponibilidad de recursos para el procedimiento de adquisición anterior. Por lo tanto, solo se debe acceder al grupo a través de ese procedimiento.

Hasta ahora todo bien, pero ¿y si un hilo no quiere esperar pasivamente a un recurso? ¿Se puede admitir la adquisición de recursos sin bloqueo? Es fácil si el semáforo admite la adquisición sin bloqueo; de lo contrario (por ejemplo, en Windows), esto será problemático. El semáforo no se puede omitir porque rompería el caso de bloqueo. Pasar por el semáforo solo si la piscina no está vacía puede llevar a un punto muerto si se realiza debajo de la cerradura, pero tan pronto como se suelte la cerradura, el resultado de la verificación de vacío se vuelve inútil. Probablemente sea factible (no lo intenté), pero seguramente lleva a una complejidad adicional significativa.

Con la variable de condición, esto se resuelve fácilmente. Aquí está el pseudocódigo con la adquisición de bloqueo:

acquire the lock 
while the resource pool is empty, 
    wait for condition variable to be signaled 
take a resource out of the pool 
release the lock 
use the resource 
acquire the lock 
put the resource back to the pool 
release the lock 
signal the condition variable 

Y en este caso no hay ningún problema para agregar sin bloqueo adquisición:

acquire the lock 
if the resource pool is not empty, 
    take a resource out of the pool 
release the lock 
if the pool was empty, return 

Como se puede ver, no se necesita ni siquiera acceder a la condición variable, y no hace daño al caso de bloqueo. Para mí, es claramente superior al uso del semáforo.

3

Grupos de conexión.

I.e. tienes 20 conexiones y 150 hilos. En ese caso, tendría un semáforo para controlar el acceso a las 20 conexiones.

+0

+1: Buen ejemplo simple, pero me pregunto si hay alguna otra situación para la que los semáforos serían buenos ... –

2

Los semáforos se pueden adquirir por un hilo y soltarse en otro. Los bloqueos generalmente no pueden hacer esto. Lo he usado cuando el hilo A termina de usar un recurso y pasa el control del recurso al hilo B. Tuve que controlar el orden para evitar interbloqueos en esta situación particular.

Cuestiones relacionadas