Volver al temario
Tema 04 · 70 páginas

Comunicación y sincronización

Tema completo Modo estudio
GUÍA DE ESTUDIO · Páginas 2224 Ver PDF

2.3. Semáforos en Linux

Material de estudio basado en la edición de 2014. Borrador pendiente de revisión editorial independiente.

Semáforos en Linux (POSIX)

Resumen

Linux ofrece semáforos POSIX dentro de su repertorio de llamadas al sistema. Se centra en semáforos sin nombre para flujos de ejecución del mismo proceso (comparten espacio de memoria lógico).

Tipo de datos

POSIX define el tipo sem_t para declarar variables de tipo semáforo. El parámetro de tipo semáforo se pasa por referencia.

Llamadas al sistema

LlamadaFunciónRetorno
sem_init(sem_t *sem, int pshared, unsigned int value)Inicializa el semáforo al valor indicado. pshared = 0 para uso entre threads del mismo proceso0 / -1 (error)
sem_wait(sem_t *sem)Espera y decrementa atómicamente0 / -1 (error)
sem_post(sem_t *sem)Incrementa atómicamente (equivale a sem_signal)0 / -1 (error)

Nota: el error puede estar relacionado con la recepción de señales de software.

Ejemplo: motor de explosión de cuatro tiempos

El programa crea 4 threads que se sincronizan con semáforos para garantizar la secuencia: Admisión → Compresión → Explosión → Escape.

Puntos clave del ejemplo:

  • Se usa un array de 4 semáforos sync_tiempo[4].
  • sync_tiempo[0] (Escape→Admisión) se inicializa en 1 para que Admisión pueda "arrancar" el motor.
  • Los demás semáforos se inicializan en 0.
  • Cada thread ejecuta sem_wait en su semáforo, realiza su tarea, luego ejecuta sem_post sobre el semáforo del siguiente tiempo: sem_post(&sync_tiempo[(t+1)%4]).
  • Se crea con compilación -pthread.
sem_t sync_tiempo[4];

void *tiempo(void *par) {
    int t = (int) par;
    while (1) {
        if (sem_wait(&sync_tiempo[t]) < 0) error();
        printf("%d %s\n", t, name[t]);
        sleep(rand() % 4);
        if (sem_post(&sync_tiempo[(t+1)%4]) < 0) error();
    }
}

int main() {
    /* sync_tiempo[0] = 1 (Escape → Admisión) */
    sem_init(&sync_tiempo[0], 0, 1);
    /* sync_tiempo[1..3] = 0 */
    sem_init(&sync_tiempo[1], 0, 0);
    sem_init(&sync_tiempo[2], 0, 0);
    sem_init(&sync_tiempo[3], 0, 0);
    /* Creación y join de threads */
}

Observaciones

  • Los semáforos sin nombre son para threads del mismo proceso.
  • Los semáforos con nombre (a través del sistema de ficheros) permiten comunicación entre procesos distintos.
  • El error en sem_wait puede deberse a la recepción de señales de software.

Ideas clave

  • POSIX ofrece sem_t con sem_init, sem_wait y sem_post.
  • sem_post equivale a sem_signal del modelo teórico.
  • Un semáforo inicializado en 1 permite el "arranque" de una cadena de sincronización.
  • El ejemplo del motor de 4 tiempos muestra sincronización cíclica entre múltiples threads.
  • Las llamadas devuelven 0 o -1; el error puede estar relacionado con señales.
Consultar el contenido original