Las semáforos y mutexes/variables de condición son buenas primitivas de muy alto rendimiento que son apropiadas para usar entre hilos o entre procesos.
Todos estos se basan en la idea (y generalmente, en la realidad) de probar y establecer u otras operaciones atómicas realizadas en la memoria compartida.
Si espera distribuir sus procesos a través de la red, los semáforos y mutexes pueden no ser adecuados para usted, solo funcionan en una sola máquina. Las tuberías y tomas son, en general, extensibles a la red.
Un breve resumen de mutexes, variables de condición y semáforos:
objetos mutex
Un mutex es una primitiva que puede ser bloqueado o desbloqueado. El proceso/hilo que lo bloqueó debe ser el que lo desbloquee. Este aspecto de propiedad permite que el sistema operativo aplique algunas optimizaciones interesantes, como herencia de prioridad y protocolo de techo de prioridad (para evitar la inversión de prioridad). sin embargo,, el mutex no tiene un recuento asociado. No puede bloquear un mutex ya bloqueado, en general, y retener la memoria que estaba "bloqueado dos veces" (hay algunas extensiones que permiten esto, creo, pero no están disponibles en todas partes)
Variables de condición
Un mutex es ideal para ... bueno, MUTual EXclusion. Pero, ¿qué sucede si necesita bloquear una condición asociada con el objeto al que tiene exclusión mutua? Para esto, usa una variable de condición, o CV. Un CV está asociado con un mutex. Por ejemplo, supongamos que tengo una cola de datos de entrada a la que mis procesos quieren acceder. Uno agarra el mutex para que pueda mirar la cola sin temor a interferencias. Sin embargo, encuentra la cola vacía y quiere esperar a que algo entre en la cola. Por lo tanto, espera en la variable de condición "cola no vacía". La parte interesante aquí es que, debido a que el CV está asociado con el mutex, el mutex obtiene automáticamente vuelto a adquirir una vez que se señala la variable de condición. Por lo tanto, una vez que el proceso se despierta después de esperar en el CV, sabe que tiene acceso exclusivo nuevamente a la cola. Lo que hace no es saber si la cola realmente tiene algo que ver -quizá dos procesos esperaron en el CV-, una cosa entró, y la primera prioridad entró y quitó la "cosa" antes de que despertara la segunda cosa arriba. Por lo tanto, cada vez que utilice un CV, es necesario volver a comprobar la condición, así:
mutex_enter(m);
while (! condition) {
cond_wait(m, c); // drop mutex lock; wait on cv; reacquire mutex
}
//processing related to condition
mutex_exit(m);
semáforos
OK, esto es mutex y variables de condición. Los semáforos son más simples. Se pueden incrementar y disminuir mediante cualquier proceso. Tienen memoria, cuentan, por lo que puedes usarlas para determinar cuántas de una condición han ocurrido. No ocurre lo mismo con las variables de condición. Además, como los semáforos se pueden disminuir en un proceso y aumentar en otro, no tienen el aspecto de propiedad, por lo que no es posible heredar la prioridad ni evitar la inversión prioritaria.
Ahora, finalmente, todos estos mecanismos requieren memoria compartida para una implementación eficiente. Esto puede estar bien para usted, pero tenga en cuenta que si cree que su aplicación se puede distribuir finalmente, entonces mutexes, variables de condición y semáforos pueden no ser para usted. Las tuberías y tomas de corriente, aunque tienen una sobrecarga mucho mayor, tienen la posibilidad de extenderse por la red de manera bastante sencilla.
semáforos POSIX pueden ser compartidos a través de procesos no relacionados, mientras que los mutex pthread no puede. – ephemient