Un semáforo se adapta limpiamente a un modelo productor-consumidor, aunque tiene otros usos. La lógica de su programa es responsable de garantizar que se realice la cantidad correcta de publicaciones para el número de esperas. Si publica un semáforo y nadie lo está esperando aún, entonces cuando lo hagan, continuarán de inmediato. Si su problema es tal que se puede explicar en términos del valor de conteo de un semáforo, entonces debería ser fácil de resolver con un semáforo.
Una variable de condición es un poco más tolerante en algunos aspectos. Puede, por ejemplo, usar cond_broadcast para despertar a todos los camareros, sin que el productor sepa cuántos hay. Y si cond_signal un condvar con nadie esperando, entonces no pasa nada. Esto es bueno si no sabes si va a haber un oyente interesado. También es la razón por la cual el oyente siempre debe verificar el estado con el mutex sostenido antes de esperar; si no lo hacen, pueden perder una señal y no despertarse hasta la siguiente (que podría ser nunca).
Por lo tanto, una variable de condición es adecuada para notificar a las partes interesadas que el estado ha cambiado: adquiere el mutex, cambia el estado, señaliza (o transmite) el condvar y libera el mutex. Si esto describe su problema, se encuentra en territorio condvar. Si diferentes oyentes están interesados en diferentes estados, puedes transmitir y cada uno se despertará, descubrirá si han encontrado el estado que desean y, si no, esperarán nuevamente.
De hecho, es muy complicado intentar este tipo de cosas con un mutex y un semáforo. El problema surge cuando quieres tomar el mutex, verificar un estado y luego esperar en el semáforo para ver los cambios. A menos que pueda liberar atómicamente el mutex y esperar en el semáforo (que en pthreads no puede), termina esperando en el semáforo mientras mantiene el mutex. Esto bloquea el mutex, lo que significa que otros no pueden tomarlo para realizar el cambio que te interesa. Por lo tanto, tendrá la tentación de agregar otro mutex de una manera que dependa de sus requisitos específicos. Y tal vez otro semáforo. El resultado es un código generalmente incorrecto con condiciones de carrera dañinas.
Las variables de condición escapan a este problema, porque la llamada cond_wait libera automáticamente el mutex, liberándolo para su uso por otros. El mutex se recupera antes de que dev_wait regrese.
IIRC es posible implementar un tipo de condvar usando solo semáforos, pero si el mutex que está implementando para ir con el condvar es necesario tener trylock, entonces es un grave scratch, y las esperas temporizadas están fuera . No recomendado. Así que no asumas que cualquier cosa que puedas hacer con un condvar se puede hacer con semáforos. Además, por supuesto, los mutex pueden tener comportamientos agradables de los que carecen los semáforos, principalmente la prevención de inversión de prioridad.
me he dado cuenta de que "semáforo inicializado correctamente" está mal definida. ¿El semáforo está configurado en 1 o en 0? Diría que debería establecerse en 0. Entonces, ¿el semáforo protege el estado de la cámara-> o no? – Blaisorblade
En el segundo fragmento, como se menciona en otras respuestas, se bloqueará el hilo mientras no se lanza mutex. Por lo tanto, su método 'sem_wait' nunca volverá porque ningún otro hilo puede adquirir el mutex y llamar a' sem_signal'. Sin embargo, no haré qué si lanzo mutex antes de 'sem_wait' y lo vuelvo a requerir después de esperar. Sé que estos pasos no son atómicos, entonces ¿qué pasará? – sevenkplus