Diferencia entre revisiones de «Mecanismos de sincronización»

De Wiki de Sistemas Operativos
Saltar a: navegación, buscar
(Optimista: revisión)
m (Optimistas: errata)
Línea 12: Línea 12:
 
       if (compartida+1 != tmp) /* compruebo si la variable compartida ha sido modificada */
 
       if (compartida+1 != tmp) /* compruebo si la variable compartida ha sido modificada */
 
               goto retry;      /* mientras operaba con el temporal */
 
               goto retry;      /* mientras operaba con el temporal */
</source lang="c">
+
</source>
  
 
Los inconvenientes de este tipo de mecanismo son dos:
 
Los inconvenientes de este tipo de mecanismo son dos:

Revisión del 09:22 30 mar 2011

Optimistas

Este mecanismo debe emplearse si el programador considera que la frecuencia de acceso a un recurso compartido es baja, es decir, que supone que la probabilidad de coincidencia de dos o más procesos al recurso compartido es baja.

El siguiente ejemplo muestra el código ejecutado por dos hilos: hx y hy de un mismo proceso.

int compartida = 1, tmp;
    retry:
      tmp = compartida;    /* anoto */
      tmp++;               /* actualizo temporal */
      if (compartida+1 != tmp) /* compruebo si la variable compartida ha sido modificada */
              goto retry;      /* mientras operaba con el temporal */

Los inconvenientes de este tipo de mecanismo son dos:

  • Se consume más memoria, pues hay que realizar una copia del recurso compartido para efectuar la comprobación.
  • En situaciones de coincidencia, se tiene que volver a realizar la operación, por tanto, se desperdician recursos de procesamiento.

Por último, si el programador ha empleado una aproximación optimista para una situación en la que la frecuencia de coincidencia es alta, podría darse el caso de que un hilo no progrese en su ejecución de manera indefinida, al tener que volver a reintentar la actualización una y otra vez hasta conseguirlo sin que haya concurrencia.

Pesimista

Se considera que la frecuencia de acceso al recurso compartido es alta. En este mecanismo disponemos de tres partes :

  • Un protocolo de entrada : en el cual se restringe el permiso de acceso para las variables compartidas.
  • Una sección crítica : donde se realizan todas las operaciones con las variables compartidas.
  • Un protocolo de salida : en el cual se restablece el permiso de acceso para las variables compartidas.

(Toda operación con una variable compartida necesita un protocolo de entrada y otro de salida)

/*Ejemplo de control pesimista suponiendo 2 hilos, hx y hy*/
int compartida = 1; no_permito_acceso_variable_compartida(); /* protocolo de entrada */ compartida++; /* sección crítica */ permito_acceso_a_variable_compartida(); /* protocolo de salida */

¿Cómo implementamos el protocolo de entrada y salida en el control de concurrencia pesimista?

Interrumpiendo la conmutación, desactivando las interrupciones, seguidamente ejecutando la sección crítica y finalmente permitiendo el acceso a las variables compartidas y activando las interrupciones.

¿Cómo implementar el control de concurrencia pesimista?

  • Espera ocupada/activa : cerrojos. Se comprueba continuamente la condición que permite franquear el protocolo de entrada
  • Espera no ocupada/no activa : semáforos, monitores y mensajes. Se pasa a estado bloqueado cuando no se puede franquear el protocolo de entrada.