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
| Llamada | Función | Retorno |
|---|---|---|
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 proceso | 0 / -1 (error) |
sem_wait(sem_t *sem) | Espera y decrementa atómicamente | 0 / -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_waiten su semáforo, realiza su tarea, luego ejecutasem_postsobre 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_waitpuede deberse a la recepción de señales de software.
Ideas clave
- POSIX ofrece
sem_tconsem_init,sem_waitysem_post. sem_postequivale asem_signaldel 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.