2.4.2 Semáforos y mútex

Como en la vida real, un semáforo es una herramienta que permite sincronizar, en este caso procesos, los cuales deben acceder a recursos sin llegar a un conflicto, que se traduciría en inconsistencias de datos, interbloqueos y problemas de concurrencia y sincronización.


Implementado, un semáforo es una estructura de datos.


Un semáforo se asemeja a un número entero en tres aspectos:

  1. Al crear el semáforo, se tiene la posibilidad de iniciar su valor con cualquier número entero. Sin embargo, una vez establecido, las únicas operaciones permitidas son incrementar (aumentar en uno) y disminuir (reducir en uno). No se permite la lectura directa del valor actual del semáforo.
  2. Al disminuir el semáforo, si el resultado es negativo, el hilo que realiza la operación queda bloqueado y no puede proseguir hasta que otro hilo incrementa el semáforo.
  3. Al incrementar el semáforo, si existen otros hilos en espera, uno de ellos se desbloquea.

    //Ejemplo:
        //Este código demuestra cómo se puede utilizar un semáforo como un mutex para proteger una sección crítica de código. 
        //Crea un hilo y un semáforo (que actúa como un mutex). 
        //Cuando cada hilo intenta imprimir su mensaje (la sección crítica),  primero debe adquirir el semáforo (mutex). 
        //Solo después de adquirir el semáforo, el hilo puede imprimir su mensaje.
                                                    
    #include <stdio.h>
    #include <pthread.h>
    #include <semaphore.h>
                        
    sem_t mutex;                                                        // Declaración del semáforo

    void* thread_func(void* arg) {
                                                                        // Espera al semáforo (mutex)
        sem_wait(&mutex);
        printf("Sección crítica del hilo\n");
                                                                        // Se libera el semáforo (mutex)
        sem_post(&mutex);
        return NULL;
    }

    int main() {
        pthread_t thread;
                                                                        // Se inicializa el semáforo (mutex) con un valor inicial de 1
        sem_init(&mutex, 0, 1); 

                                                                        // Se crea un hilo
        pthread_create(&thread, NULL, thread_func, NULL); 
                                                                        // Espera al semáforo (mutex) - sección crítica del hilo principal
        sem_wait(&mutex); 
        printf("Sección crítica del hilo principal\n");
                                                                        // Se libera el semáforo (mutex)
        sem_post(&mutex); 

                                                                        // Espera a que termine el hilo
        pthread_join(thread, NULL);
                                                                        // Se destruye el semáforo (mutex)
        sem_destroy(&mutex); 
        return 0;
    }
                    

Código 8. Semáforo con mutex.

Reflexiona la siguiente pregunta que será tratada en la sesión de clase.

¿Cual ejemplo es implementado en aplicaciones de uso cotidiano que eviten las condiciones de carrera, abrazo mortal y exclusión mutua?