CONCURRENCIA DE PROCESOS Preparado por: Angel Chata Tintaya (angelchata@hotmail.com) Resumen Los procesos comparten variables globales, comparten y compiten por recursos, se ejecutan simultáneamente intercalándose en el CPU, operando en una red. Los procesos tienen que comunicarse entre ellos para no interferirse al compartir los recursos, al acceder a las mismas variables. I. PRINCIPIOS GENERALES 1. Exclusión mutua. Es la capacidad de prohibir a otros procesos a acceder a un recurso cuando otro ya obtuvo el permiso. 2. Semáforos. Indicador que registra si un recurso esta disponible. 3. Mensajes. Permiten comunicación y sincronización de procesos. 4. Interbloqueo. Bloqueo permanente de procesos que compiten por recursos o se comunican entre ellos. Exclusion Mutua Recurso Mensajes S Recurso Semaforo Interbloqueo II. EXCLUSIÓN MUTUA Ejemplo 1. Se quiere tener constancia del número de visitantes que hay en un Jardín. Hay dos puertas y asociado a cada puerta un proceso. : Cuando entra una persona el proceso incrementa x : x := x + 1 : Cuando sale una persona el proceso decrementa x : x := x 1 2. En esta situación se puede producir una mala actualización de la variable x. El planificador de procesos puede permitir el entrelazado de las operaciones elementales de cada uno de los procesos. 3. En el jardín hay 7 personas y por una puerta ingresa uno mientras que por otra puerta sale otra persona. Entrar al jardín (SCHED_RR) x := x + 1 Salir del jardín (SCHED_RR) x := x 1 Traza STORE *x -> CPU *x = ADD 1 -> CPU STORE *x -> CPU STORE CPU -> x *x = SUB 1 -> CPU STORE CPU -> x *x = Sección Crítica Una impresora es un recurso critico, ya que no es compartible por intervalos de tiempo. Una vez que un documento empiece a imprimirse, no se podrá imprimir otro; si no saldrían líneas intercaladas en el papel. La parte del programa que usa la impresora es la sección crítica. ma781.tripod.com 1 de 7
1. Se denomina Sección crítica a aquellas partes de los procesos concurrentes que no pueden ejecutarse de forma concurrente. 2. Si un proceso entra a ejecutar una sección crítica en la que se accede a unas variables compartidas, entonces otro proceso no puede entrar a ejecutar una sección crítica en la que se modifique las variables compartidas con el anterior. 3. Las secciones críticas se agrupan en clases, siendo mutuamente exclusivas las regiones críticas de cada clase 4. La exclusión mutua se consigue con protocolos que bloqueen el acceso a la sección crítica mientras es utilizada por un proceso. 5. Si un proceso necesita una región crítica prende un flag y espera su turno. 6. Cada proceso debe obtener un turno para usar la región crítica. III. EXCLUSIÓN MUTUA POR HARDWARE Por inhabilitación de interrupciones. 1. Un proceso en ejecución puede ser interrumpido por el Dispatcher. 2. Deshabilitando la interrupción de procesos se garantiza la exclusión mutua. 3. Se limita al procesador a intercalar varios procesos. 4. Solo es útil en maquinas con un solo procesador 5. En maquinas multiprocesador, deshabilitar la interrupción de un solo procesador no garantiza la exclusión mutua. Los otros procesadores pueden requerir los recursos. while (true) { /*deshabilitar interrupcion*/ /*habilitar interrupcion*/ Por instrucciones en lenguaje de maquina. 1. Se ejecutan en un solo ciclo de instrucción de lenguaje de maquina. 2. No esta sujeto a interrupciones. 3. Realiza dos acciones automáticamente. 4. La Instrucción testset (comparar y fijar). Examina el argumento si es 0 lo cambia por 1 y devuelve true; en otro caso no se modifica el valor y retorna falso. ma781.tripod.com 2 de 7
boolean testset (int i) { if (i==0) { i = 1; return true; else { return false; 4.1. Se da un valor inicial al cerrojo = 0. 4.2. El único proceso que puede ingresar a la sección crítica es aquel que encuentre el cerrojo en 0. 4.3. Todos los demás procesos están en espera en el bucle while. 4.4. Cuando el proceso ya termine la sección crítica, abre nuevamente el cerrojo haciendo cerrojo = 0. 4.5. El primer proceso que ejecute testset será el que ejecute la sección crítica. int cerrojo; while (!testset(bolt)) { /* hacer nada */ cerrojo = 0; cerrojo = 0; 5. La Instrucción exchange (intercambiar valores). Intercambia el contenido de un registro con el de una posición de memoria. void exchange(int register, int memory) { int temp; temp = memory; memory = register; register = temp; 5.1. Se inicia con una variable compartida cerrojo = 0. 5.2. Cada proceso tiene una variable local iniciada en 1. clave = 1. 5.3. El único proceso que puede entrar a la sección crítica es aquel que encuentre el cerrojo abierto en 0; colocándolo en 1 (cerrado). 5.4. Cuando un proceso abandona la sección crítica, vuelve a abrir el cerrojo colocándolo en cero. int cerrojo; int clave; clave = 1; while (clave!=0) { exchange(clave,cerrojo); exchange(clave,cerrojo); cerrojo = 0; 6. Presenta las siguientes desventajas. 6.1. Un proceso que esta esperando, consume tiempo de CPU en el bucle while. 6.2. Puede producirse interbloqueo. Si un proceso SCHED_RR usa la sección crítica primero y luego es interrumpido por un proceso SCHED_FIFO. ma781.tripod.com 3 de 7
IV. SEMÁFOROS Un nuevo estado: en ESPERA. Dos o más procesos pueden cooperar mediante señales de forma que pueda obligar a detenerse a un proceso hasta que reciba una señal para que continúe. 1. Se usa una variable llamada semáforo para intercambiar señales. 2. Si un proceso esta esperando una señal, se suspende hasta que la señal se envie. 3. WAIT y SIGNAL son operaciones que no pueden interrumpirse. (Se ejecutan en un solo ciclo de lenguaje de maquina) 4. Se mantiene una cola de procesos en ESPERA en el semáforo. 5. La forma de liberar a los procesos de la cola en ESPERA es mediante una política primero en entrar, primero en salir (POLICY_FIFO) Algoritmo para un semáforo binario. 1. Un semáforo esta compuesto por una cola de procesos que esperan que el semáforo les dé el paso libre. 2. En la operación wait(s), si el semáforo esta libre (valor 1), cierra el paso (valor 0). 3. En la operación wait(s), si el semáforo cierra el paso (valor 0), coloca el proceso en la cola de espera de este semáforo. 4. En la operación signal(s), si la cola de espera esta vacía, el semáforo se coloca como libre (valor 1) 5. En la operación signal(s), si la cola de espera no esta vacía, el primer proceso de la cola en espera se coloca en la cola de preparados, listos para que el PCP lo lleve al CPU para su ejecución. struct semaforo_binario { enum(zero,one) value; queuetype queue; ; void waitb(semaforo_binario s) { if (s.value == 1) s.value=0; else { /*colocar este proceso P en la cola s.queue*/ /*bloquear el proceso*/ void signalb(semaforo_binario s) { if (s.queue.is_empty()) s.value=1; else { /*remover el proceso P de la cola s.queue*/ /*colocar el proceso P como listo para ejecucion*/ ma781.tripod.com 4 de 7
Exclusión mutua con semáforos. 1. Sean n procesos en el vector P(i) 2. En cada proceso se ejecuta un wait(s) antes de la ejecución de la sección crítica. 3. El primer proceso que cambie el semáforo lo hará del valor 1 al valor 0, cerrando el paso. 4. Los demás procesos que encuentren el semáforo cerrado (valor 0) se encontraran en la cola de espera de este semáforo. 5. Una vez que el primer semáforo termine la sección crítica, realizara un signal(s). 6. Un signal(s) habilitara para su ejecución el siguiente proceso de la cola de espera del semáforo. 7. Un signal(s) colocara el valor del semáforo en 1. 8. El semáforo se inicia con 1 para que el primer proceso ingrese ala sección crítica con un wait(s). semaforo s=1; wait(s); signal(s); Ejemplo de semáforo binario 1. Son 3 procesos que usan el semáforo lock para acceder a una sección crítica. 2. Con cada wait(lock) se cambia el valor del semáforo a 0 o se agrega este proceso a la cola de espera del semáforo lock. 3. Con cada signal(lock) se toma un proceso de la cola de espera del semáforo para su ejecución en el CPU y además de no haber mas procesos en la cola de espera, se coloca el valor del semáforo en 1. ma781.tripod.com 5 de 7
V. MENSAJES 1. Permite el intercambio de información entre procesos. 2. La comunicación entre mensajes necesita de un proceso emisor, de un proceso receptor y la información que debe intercambiarse. 3. Las operaciones básicas son: enviar(destino, mensaje) recibir(origen, mensaje) 4. La comunicación por mensajes requiere que se establezca un enlace entre el receptor y el emisor. 5. Fuerza la exclusión mutua. Direccionamiento 1. Direccionamiento directo. 1.1. La operación enviar() incluye una identificación del proceso destino 1.2. La operación recibir() puede incluir la identificación del proceso origen del mensaje. (Procesos cooperantes) 1.3. La operación recibir() también puede no saber cuál es el proceso origen del mensaje (Como un servicio de impresoras, recibirá solicitudes de impresión de cualquier proceso). El parámetro origen se utilizara como respuesta de que el mensaje ha sido recibido. 2. Direccionamiento indirecto. 2.1. Los mensajes no se envían directamente al receptor, sino a una cola para su posterior procesamiento. 2.2. Las colas son llamadas buzones (mail box). 2.3. Los procesos envían mensajes a un buzón y es un proceso quien toma los mensajes del buzón para su procesamiento. 3. Desacoplamiento del direccionamiento indirecto. Permite flexibilidad en el manejo de mensajes. 3.1. Un emisor y un receptor. Es un enlace privado de comunicación entre dos procesos. 3.2. Muchos emisores y un receptor. Un proceso ofrece un servicio a muchos procesos. En este caso el buzón se llama puerto. (programas cliente / servidor) 3.3. Un emisor y muchos receptores. Un mensaje se difunde a un conjunto de procesos receptores. (Upgrade de programas por internet). 3.4. Muchos emisores y muchos receptores. (envío de e-mails). Sincronización Emisor y Receptor pueden o no pueden bloquearse; el emisor la respuesta de que el mensaje ha sido recibido por el receptor o el receptor esperando algún mensaje de un emisor. 1. Emisor con bloqueo y Receptor con bloqueo. Emisor Síncrono 1.1. Ambos, tanto receptor como emisor son bloqueados hasta que el mensaje sea entregado. 1.2. Se llama rendezvous. 1.3. Permite una sincronización fuerte de procesos. 1.4. Ejemplo: Procesos cooperantes. 2. Emisor sin bloqueo y Receptor con bloqueo. Emisor Asíncrono 2.1. El emisor continua su procesamiento, enviando mensajes tan rápido como sea posible. 2.2. El receptor se bloqueo hasta que llegue el mensaje solicitado. ma781.tripod.com 6 de 7
2.3. Es la combinación más útil de sincronización. 2.4. Ejemplo: Connect desde un programa Oracle (cliente) hacia un Listener Oracle (servidor ). 3. Emisor sin bloqueo y Receptor sin bloqueo. 3.1. Nadie debe esperar. 3.2. Ejemplo: El MS-Word continua su proceso mientras el servicio de impresión de diversos procesos continúan. Emisor con bloqueo Receptor con bloqueo Partes de un mensaje Emisor sin bloqueo Receptor con bloqueo Emisor sin bloqueo Receptor sin bloqueo 1. Cabecera 1.1. Tipo de mensaje 1.2. Proceso Destino (buzón, puerto) 1.3. Proceso Origen (cliente) 1.4. Longitud del mensaje 1.5. Información de control (prioridad, siguiente mensaje, contador de secuencia) 2. Cuerpo Exclusión Mutua 1. Envío sin bloqueo, Recepción con bloqueo 2. Un conjunto de procesos comparten un buzón llamado mutex. 3. El buzón al inicio contiene un mensaje de contenido arbitrario. 4. Un proceso que desea usar la sección crítica, recibe ese mensaje (quitándose del buzón) 5. Puesto que la recepción es con bloqueo, ningún otro proceso podrá ingresar a la sección crítica (Ya que no existe mensajes en el buzón). 6. Una vez que ha usado la sección crítica, devuelve el mensaje al buzón. 7. Así el mensaje sirve como posta entre un mensaje y otro para usar la sección crítica. message msg; recibir(mutex,msg); enviar(mutex,msg); crear_mailbox(mutex); enviar(mutex,null); ma781.tripod.com 7 de 7