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.
Relacionados: http://stackoverflow.com/questions/2350544/in-what-situation-do-you-use-a-semaphore-over-a-mutex-in-c –
Un ejemplo: http: // desbordamiento de pila.com/questions/2375132/releasesemaphore-does-not-release-the-semáforo/2375370 # 2375370 –