Sincronización de Procesos y Hilos en Sistemas Operativos: Módulos del Kernel, Cerrojos, Semáforos y Problemas Clásicos

Informática4,36 KB

Ejemplo de los nadadores que tienen barreras

TODO: ejemplo de los nadadores que tienen barreras y es completito.

Módulos para el kernel

  • Los módulos se ubican en /lib/modules.
  • Para ver los módulos cargados: lsmod.
  • Código de un módulo: debe contener las funciones init_module y cleanup_module.
  • Cargar el módulo: insmod.
  • Descargar el módulo: rmmod.
  • Dispositivos de caracteres (chrdev): para crear el archivo se asigna un major y un minor.
  • Creación del archivo de dispositivo: mknod -m 666 (permisos) c (tipo de dispositivo: carácter).

Cerrojo (mutex)

Atributos: estado, cola y hilo_propietario.

  • lock: si el estado está cerrado, añade el hilo a la cola, suspende el hilo y, al despertar, lo borra de la cola. Si el estado está abierto, cierra el cerrojo, asigna como propietario este hilo.
  • unlock: si soy el propietario, abro el estado, pongo propietario = null; si la cola no está vacía, despierto un hilo.

Semáforo

Atributos: cola de procesos y contador.

  • wait: decrementa el contador (contador--); si el contador es menor que 0, bloquea el proceso.
  • signal: incrementa el contador (contador++); si hay procesos bloqueados, libera un proceso.

Variable de condición

Compuesta por una cola de espera y un mutex.

  • wait: añade el hilo a la cola, libera el mutex, duerme el hilo y, al despertar, recupera el mutex.
  • signal: si la cola no está vacía, despierta un hilo.
  • broadcast: despierta a todos los hilos en espera.

Algoritmo de Peterson

while (turno && interesado[i]); // espero
// sección crítica
interesado[i] = false;
// fin sección

Instrucciones máquina

Test and Set (T&S)

while (tas(dirMem, 1)) {}
// sección crítica
*dirMem = 0;

Swap / Exchange

tmp = 1;
while (tmp) {
    xchg(dirM, tmp);
    // sección crítica
    *dirM = 0;
}

LL/SC (Load-Linked / Store-Conditional)

while (1) {
    while (ll(dirM));
    if (sc(dirM, 1)) break;
    // si no, otra vez al load-link
}
// sección crítica
*dirM = 0;

Productor/consumidor con variables de condición

buffer[max_buff];
indProd = 0, indCons = 0;
mutex_t m;
cond_t event;

void productor() {
    mutex_lock(&m);
    while (n_elementos == max_buff) cond_wait(&event, &m);
    cond_broadcast(&event);
    mutex_unlock(&m);
    ...
}

void consumidor() {
    mutex_lock(&m);
    while (!n_elementos) cond_wait(&event, &m);
    cond_broadcast(&event);
    mutex_unlock(&m);
    ...
}

Productor/consumidor con semáforos

void productor() {
    int dato, i;
    for (i = 0; i < N; i++) {
        // producir dato
        dato = producir_dato();
        sem_wait(&huecos);      // un hueco menos
        buffer[prod] = dato;
        prod = (prod + 1) % max_buff;
        sem_post(&elementos);   // un elemento más
    }
    thread_exit(0);
}

void consumidor() {
    int dato, i;
    for (i = 0; i < N; i++) {
        sem_wait(&elementos);   // un elemento menos
        dato = buffer[cons];
        cons = (cons + 1) % max_buff;
        sem_post(&huecos);      // un hueco más
        consumir_dato(dato);
    }
    salir_hebra(0);
}

Lectores/escritores con semáforos

void lector() {
    while (1) {
        sem_wait(&sem_lec);
        n_lectores++;
        if (n_lectores == 1) sem_wait(&cerrojo);
        sem_post(&sem_lec);
        // leer recurso
        sem_wait(&sem_lec);
        n_lectores--;
        if (n_lectores == 0) sem_post(&cerrojo);
        sem_post(&sem_lec);
    }
}

void escritor() {
    while (1) {
        sem_wait(&cerrojo);
        dato += 2; // modificamos recurso
        sem_post(&cerrojo);
    }
}

Descargar

PDF Word HTML