You are on page 1of 30
Sincronizacion y comunicacion de procesos Las tareas que corren en un sistema se diseflan para llevar a cabo un objetivo comin y, por lo tanto, es necesario que algunas de ellas se comuniquen entre sf; adems, en su ejecucién competiran por conseguir los recursos del sistema, una zona de datos especificos, o un dispositivo de £/S y dicha competicién se debe regular proporcionando los mecanismos adecuados para la sincronizacién de los procesos. También se precisa esta sincronizacién para establecer un orden de ejecucién de las tareas que sea coherente con el objetivo global del sistema, Las técnicas de sincronizacién que se presentan en este tema son el fundamento del procesamiento concurrente. Existen dos métodos bisicos de comunicacién entre procesos: comparticiin de datos e intereambio de informacién, En este tema se trata inicialmente el problema de la comunicacién entre procesos mediante comparticién de datos y se realiza su introduccién estudiando el problema de la exclusién mutua, Se introducen después los semdforos, que son un procedimiento sencillo, pero potente, para la solucién de los problemas de Ia exclusién mutua y de la sincronizacién entre procesos. Los semaforos constituyen el mecanismo basico fundamental para el problema de la sincronizacion, A continuacion se sigue con el estudio de los monitores. Estos proporcionan un mecanismo alternativo al de los semiforos, con una solucién més estructurada al proporcionar abstraccién de los datos que se comparten, Los mensajes proporcionan una solucién al problema de la concurrencia de procesos que integra Ia sincronizacién y la comunicacién entre ellos y resulta adecuado tanto para sistemas centralizados como para distribuidos. El método de intercambio de informacién mediante mensajes necesita siempre de un proceso emisor, de otro receptor asi como de la informacién que debe intercambiarse. inalmente se trata el problema del interbloqueo (deadlock), que aparece frecuentemente en los sistemas, multitarea y en los multiprogramados. Una situacion de interbloqueo se produce cuando dos o mas procesos entran en un estado que imposibilita a cualquiera de ellos salir del estado en que se encuentra. A dicha situacién se llega porque cada proceso adquiere algin recurso necesario para su operacion a la vez que espera aque se iberen otros recursos que retienen otros procesos, llegandose a una situacién que hace imposible que ninguno de ellos pueda continuar. Se analizan las cuatro condiciones que, de forma simultanea, se deben cumplir para que se produzca un interbloqueo y se proponen diferentes estrategias para manejar dicho problema, 102 3 Sincronizacion y comunicacién de procesos Exclusion mutua El método més sencillo de comunicacidn entre los procesos de un programa concurrente es el uso comiin de unas variables de datos. Esta forma tan sencilla de comunicacién puede llevar, no obstante a errores en el programa, ya que el acceso concurrente puede hacer que la accién de un proceso interfiera en las acciones de otro de una forma no adecuada. Aunque nos vamos a fijar en variables de datos, todo lo que sigue seria vilido con cualquier otro recurso del sistema que s6lo pueda ser utilizado por un proceso a la vez ames Tet 3.4.1 Ejemplot Consideramos una variable x compartida entre dos procesos A y B que pueden incrementar o deerementar la variable dependiendo de un determinado suceso. Este situacién se plantea, por ejemplo, en un problema tipico de la programacién concurrente conocido como el problema de los jardines. En este problema se supone que se desea controlar el niimero de visitantes unos jardines. La entrada y la salida a los jardines se puede realizar por dos puntos que disponen de puertas giratorias. Se desea poder conocer en cualquier momento el nlimero de visitantes a los jardines, por lo que se dispone de un computador con conexidn en cada uno de los dos puntos de entrada que le informan cada vez que se produce una entrada o una salida. Asociamos el proceso P, a un punto de entrada y el proceso P. al otro punto de entrada, Ambos procesos se llevar la cuenta del nimero de visitantes, sjecutan de forma concurrente y utilizan una tinica variable x para incremento 0 decremento de la variable se produce cada vez que un visitante entra o sale por una de las puertas. Asi, la entrada de un visitante por una de las puertas hace que se gjecute la instruccién wextl ‘mientras que la salida de un visitante hace que se ejecute la instruccién rex-l Si ambas instrucciones se realizaran como una unica instruceién hardware, no se plantearia ningin problema y el programa podria funcionar siempre correctamente, Esto es asi porque en un sistema con un linico procesador sélo se puede ejecutar una instruccién cada vez y en un sistema multiprocesador se arbitran mecanismos que impiden que varios procesadores accedan a la vez a una misma posicién de memoria, El resultado seria que el incremento o decremento de la variable se produciria de forma secuencial pero sin interferencia de un proceso en la accién del otro. Ahora bien, la actualizacion de la variable se realiza mediante Ia ejecucién de otras instruceiones mis sencillas, como son las usuales de: 344 Exclusién mutua 103 a) Copiar el valor de x en un registro del procesador. b) Incrementar el valor del registro. ¢) Almacenar el resultado en la direccién donde se guarda x ‘Aunque los procesos P; y P3 se supone que se ejecutan en distintos procesadores (Io que no tiene porque ser cierto en la realidad) ambos usan la misma posicién de memoria para guardar el valor dex. Se puede dar la situacién de que se produzca intromisién de un proceso en el otro, de forma que el planiticador de procesos permita el entrelazado de las operaciones elementales anteriores de cada uno de los procesos, lo que inevitablemente originard errores. Si, por ejemplo, se produce el siguiente orden de operaciones: 1) Py rga el valor de x en un registro de su provesador. 2) P) carga el valor de x en un registro de su procesador. 3) P> incrementa el valor de su registro. 4) Py incrementa el valor de su registro. 5) P, guarda el valor de su registro en la direccién de memoria de x. 6) Py guarda el valor de su registro en la direccién de memoria dex se perderd un incremento de la variable x. Este tipo de errores son muy dificiles de detectar mediante test del programa, ya que el que se produzcan depende de la temporizacién de dos procesos independientes. El ejemplo muestra de forma clara la necesidad de sincronizar la actuacién de ambos provesos de forma que no se produzcan interferencias entre ellos en determinadas situaciones. Para evitar este tipo de errores se pueden identificar aquellas regiones de los procesos que aeceden a variables compartidas y dotarlas de la posibilidad de ejecucién como si fueran una iinica instruccién. Se denomina seceién critica a aquellas partes de los procesos concurrentes que no pueden ejecutarse de forma coneurrente o, también, que desde otro proceso se deben ver como si fueran una tinica instruccién, Esto quiere decir que si un proceso entra a ejecutar una seccién critica en la que se accede a unas variables compartidas, entonces otro proceso no puede entrar a ejecutar una regién critica en la que se modifique las variables compartidas con el anterior Las secciones criti criticas de cada una. Para conseguir dicha exclusién se deben implementar protocolos software que impidan © bloqueen el acceso a una seccidn critica mientras esté siendo utilizada por un proceso, La Figura 3.1 muestra una abstraccién del problema de la exclusion mutua. Las secuencias 1 y 2 representan un cédigo secuencial que no requiere el acceso a ningiin recurso o area comiin de memoria y que, por lo tanto, pueden ejecutarse de forma concurrente sin ningtin peligro de que se produzcan intromisiones. La seccidn critica es la parte que debe protegerse de interferencias de otras procesos. Los protocolos son la parte de cédigo dedicada a asegurar que la seccién critica se ejecuta de forma exclusiva, Resulta adecuado que tanto la seecién critica como los protocolos sean lo mis breve posible para que las secuencias representen laparte significativa del cédigo y pueda aprovecharse al maximo el paralelismo entre las tareas. Ss se pueden agrupar en clases, siendo mutuamente exclusivas las secciones 104 3 Sincronizacién y comunicacién de procesos secuencia | —_> pre-protcole ———> ogueo Seecisn secon eftiea —> post prtocolo — desbloqueo Figura3.1: Problema de la exclusién mutua 3.1.2 Bloqueo mediante el uso de variables compartidas ‘Vamos a presentar en este apartado una forma de realizar el bloqueo de una seccin critica mediante el uso de una variable compartida de tipo booleano que se suele denominar indicador (flag). [remos realizando una serie de refinamicntos del algoritmo que servirdn para ir poniendo de manifiesto el tipo de problemas que suelen presentarse en la implementacidn de Ia concurrencia entre procesos. Asociaremos a cada recurso que se comparte un flag. Antes de acceder al recurso, un proceso debe examinar el indicador asociado que podré tomar dos valores (true o false) que indicarin, de forma respectiva, que el recurso esta siendo utilizado o que esta disponible. Elejemplo muestra el uso de un indicador para efectuar la exclusién mutua entre dos procesos. Sia ejemplo? J* Exelusién Mutua: Uso de un indicador*/ Program/module Exclusin_Mutua_t var flag: boolean; process P1 begin loop while flag = true do 1M" Espera a que el dispositivo se libere */ end: flag := true; 3+4 Exclusion mutua 105 P* Uso del recurso Seccién Critica */ flag := false; P* resto del proceso */ end end Pl; process P2 begin Toop while flag = true do /* Espera a que el dispositivo se libere */ end: flag:= true; 7 Uso del recurso Seccién Critica *! #* resto del proceso */ end end P2; begin /* Exclusion_Mutua_1*/ flag := false; cobegin Pl; P2; coend end Exclusién_Mutua_1 La ejecucién concurrente de los procesos la indicaremos mediante la estructura cobegin/coend. La palabra cobegin indica el comienzo de la ejecucién concurrente de los procesos que se sefalan hasta la sentencia eoend. La accién de bloqueo se realiza con la activacién del indicador y la de desbloqueo con su desactivacion. El programa no resuelve el problema de la exclusién mutua ya que al ser fa comprobacién y la puesta del indicador a falso operaciones separadas, puede ocurrir que se entrelace el uso del recurso por ambos procesos. La Figura 3.2 muestra esta posibilidad con dos procesos que desean utilizar una impresora. Si el sistema dispusiera de una instruccién que permitiera comprobar el estado y modificarlo simulténeamente, el programa permitiria el uso del recurso sin entrelazamiento. En ausencia de una instruccién de este tipo, intentamos usar dos indicadores para resolver el problema de la exclusion mutuas asociamos un indicador a cada uno de los proceso. Ambos procesos pueden leer los dos indicadores, pero s6lo pueden modificar ef que tienen asociado, Esto evita el problema de que los dos procesos actualicen de forma simulténea el mismo indicador. Antes de acceder al recurso un proceso debe activar su indicador y comprobar que el otro no tiene su indicador activado. El ejemplo siguiente muestra el programa del ejemplo anterior realizado con dos indicadores. 106 3 Sincronizacién y comunicacién de procesos Proceso 1 Proceso 2 | ot suspendida flag = | {toma la impresora asa impresoras _ —————sl | flag area suspendida tsaimpresra | us impresora idee a impresora r flag == 0 bers a impresora Figura3.2: Uso de un indicador para compartir una impresora 34 Exclusion mutua 107 mm cE: 34.4 Ejemplo3 p ‘usin Mutua: Uso de dos indicadores*/ program/module Exclusién_Mutua var flag! flag2: boolean; procedure bloqueo (var mi_flag, su_flag: boolean); rue; /*sefiala la intenci6n de usarel recurso*/ while su_flag do ; end /* espera a que se libere el recurso */ end bloqueo: procedure desbloqueo (var mi_flag: boolean); begin mi_flag:= fak end desbloqueo; process PI begin loop bloqueo (flagl, flag2); F* Uso del recurso Secci6n Critica */ desbloqueo (flag): F* resto del proceso */ end end PI; process P2 begin loop bloqueo (flag2. flag): /* Uso del recurso Seccisn Critica */ desbloqueo (fag2); Presto del proceso */ end end P2: begin /* Exclusi6n_Mutua_2/ flag! := false; flag? cobegin 108 3 Sincronizacién y comunicacién de procesos Pl; P2, coend end Exclusién_Mutua_2; EI mecanismo de bloqueo y de desbloqueo se obtiene mediante dos procedimientos. Para bloquear el acceso a la seccién critica ambos procesos Haman al procedimiento de bloqueo pero con los indicadores en distinto orden, La solucién tiene el inconveniente de que durante la espera de la liberacién del recurso, el proceso permanece ocupado, lo que se denomina espera activa. Pero hay un problema mayor. Supongamos, {que ambos procesos realizan la llamada al bloqueo de forma simulténea, Cada proceso puede poner su propio indicador y comprobar el estado del otro. Ambos verdn los indicadores contrarios como ocupados y permanecerdn a la espera de que el recurso quede liberado, pero esto no podra suceder al no poder entrar rninguno en su seccién critica. Esta accién se conoce como interbloqueo (deadlock). El interbloqueo se produce porque la desactivacién del indicador asociado a un proceso se produce una vez que se ha completado el acceso a la seccién critica. Se puede intentar resolver el problema haciendo que el proceso desactive su propio indicador durante la fase de bloqueo siempre que encuentre que el indicador del otro proceso esté activado, El ejemplo siguiente muestra el procedimiento de bloqueo con esta solucién. mecen rea 3.1.5 Ejemplo4 procedure bloqueo (var mi_ftag, su_flag: boolean); begin ini flag = true; while su_flag do mi_flag = fatse; mi_flag := true; end; end bloqueo: El algoritmo permite que en caso de interbloqueo se pueda proseguir siempre que no exista una completa sincronizacién entre los dos procesos, ya que en el caso bastante improbable, pero que pudiera darse, de que los dos procesos realicen exaciamente las mismas operaciones a la vez, se encontrarian permanentemente con los indicadores contrarios activados. Otro problema con este algoritmo es que puede permitir que un proceso deje su seccién critica y vuelvaa entrar mientras que ¢l otro proceso desactiva su indicador en la seccidn de bloqueo. El que un proceso no pueda progresar porque se lo impida otro proceso o grupo de procesos se denomina cierre (lockout o starvation), Veamos ahora dos soluciones al problema de la exclusion mutua que evitan el interbloqueo y el cierre. 3.1.6 Algoritmo de Peterson Una posible estrategia es la proporcionada por Peterson (1981). solucién se introduce una variable adicional, que denominaremos turno, que solamente resultara itil cuando se produzea un problema de 3-4 Exclusién mutua peticion simulténea de acceso a la seceién critica /P Exclusién Mutua: Solucién de Peterson*/ program/module Exclusiéa_Mutua_P; var flag, flag2: boolean; turno: integer; procedure bloqueo (var mi_flag, su_flag: boolean: su_turno: integer): begin mi_flag := true; tuo = su_tumno; while su_flag and (turno end bloqueo: u_turno) do: end. procedure desbloqueo (var mi_flag: boolean); begin mi_flag -= false; end desbloqueo; process P! begin loop bloqueo (flag! flag2, F* Uso del recurso Seccisn Critica */ desbloqueo (flag); P* restodel proceso */ end end Pl: process P2 begin loop bloqueo (flag2, flag. 1) P* Uso del recurso Seccién Critica"! desbloqueo (flag2); F* resto del proceso */ end end P2; begin /* ExclusiGn_Mutua_P*/ flagl := false; flag? := false: cobegin 109 110 3 Sincronizacién y comunicacién de procesos Pl; P2; coend end Exclusién_Mutua_P; Si sélo uno de los procesos intenta acceder a la seccién critica lo podra hacer sin ningiin problema, Sin embargo, si ambos intentan entrar a la vez el valor de turno se pondré a 1 y 2 pero sélo un valor de ellos permaneceré al escribirse sobre el otro, permitiendo el acceso de un proceso a su seccién critica Elalgoritmo permite resolver el problema de la exclusiGn mutua y garantiza que ambos procesos usarén de forma consecutiva el recurso en el caso de que lo soliciten a la vez-y se impediré el cierre del otro proceso. Si, por ejemplo, P, ha entrado en su seccisn critica bloqueando el acceso de P, éste entrar una vez haya finalizado aquél, ya que cuando P, sale de su regién critica desactiva su indicador, permitiendo el acceso de Py; si una vez que P; sale de su seccién critica P no esté en ejecucidn, P; debera permanecer en espera hasta que P, haya entrado y desactive su indicador. De esta manera se evita que P; pueda quedar relegado por P, en el uso del recurso, es decir ambos gozan de la misma prioridad en la utilizacién del recurso. 3.1.7 Algoritmo de Dekker La solucién al problema de la exclusién mutua que sigue se atribuye al matemético holandés T. Dekker, y fue presentada por Dijkstra en 1968, Se utiliza, al igual que en la solucién de Peterson, una variable turno. Ahora la variable sirve para establecer la prioridad relativa de los dos procesos y su actualizacién se realiza en la seccién critica, lo que evita que pueda haber interferencias entre los procesos. /* Exclusién Mutua: Solucin de Dekker*/ program/module Exclusién_Mutua_D; var flag flag2: boolean; turno: integer; procedure bloqueo (var mi_flag, su_flag: boolean; su_turno: integer); begin mi_flag = true; while su_flag do /* otro proceso en la seccitn critica */ ifturno = su_turno then mi_flag >= false; while turno = su_turno do :/* espera a que el otro acabe */ end; mith end; end; end bloqueo; Procedure desbloqueo (var mi_flag: boolean; su_turno: integer); rue: 3-4 Exclusién mutua 11 begin tumo :=su_turno; mi_flag := false; end desbloqueo; process Pi begin loop bloqueo (flag, flag?, 2) P* Uso del recurso Seccién Critica */ desbloqueo (flag 2); /* resto del proceso */ end end PI; process P2 begin loop Dbloqueo (flag2, flag, 1); /* Uso del recurso Seccién Critica "/ desbloqueo (flag2, 1); F* resto del proceso */ end end P2; begin /* Exclusién_Mutua_P*/ flagl := false; flag? = false: tumo:= 1; cobegin Pi P2: coend end Exclusién_Mutua_D; El programa se inicia con el valor de tw-no igual a 1, 1o que da prioridad al proc 0 Py, Si ambos procesos piden a la vez el acceso a su seccidn critica, ponen en activo sus respectivos indicadores y comprueban si el indicador del otro esta activado, Ambos encuentran que si, por lo que pasan a evaluar el tummo. El segundo se encuentra con que no es su tumo, desactiva su indicador y se queda en espera de que lo sea. P; comprueba que si es el suyo y pasa a valorar el estado del indicador de P2, entrari en su seceién critica y dari el turno a P2 antes de desactivar su indicador. Esto permite que el proceso P) gane el acceso a su seccién critica aunque el proceso P, haga una nueva solicitud de entrar a la region critica inmediatamente después de desactivar su indicador. Los algoritmos de Peterson y Dekker se pueden extender, aunque no de manera sencilla, al caso mis 412 3 Sincronizacién y comunicacién de procesos general en el que haya n procesos en ejecucién concurrente; pero no son soluciones adecuadas ya que la espera de acceso a un recurso siempre se realiza de forma “ocupada” (espera activa). El proceso se queda permanentemente comprobando una variable, lo que puede suponer un derroche de los recursos del sistema. Si, por ejemplo, se dispone de un tinico procesador, éste tendré que ocupar una parte de su tiempo en la comprobacién reiterada de una variable. 3:2 Semaforos 113 Semaforos Dijkstra dio en 1968 una solucién elegante y sencilla al problema de la exclusion mutua con la introduccién él concepto de semiforo binario. Esta técnica permite resolver la mayoria de los problemas de sineronizacién entre procesos y forma parte del disefio de muchos sistemas operativos y de lenguajes de programacién concurrentes. Un semaforo binario es un indicador de condicién (S) que registra si un recurso esta disponible o no. Un seméforo binario s6lo puede tomar dos valores: 0 y 1. Si, para un semaforo binario, S= | entonces el recurso esti disponible y la tarea lo puede utilizar; si S=0 el recurso no esta disponible y el proceso debe esperar Los seméforos se implementan con una cola de tareas o de condicién a la cual se afiaden los procesos que «tin en espera del recurso, Sélo se permiten tres operaciones sobre un semaforo: 1) Iniciatiza, 2) Espera (w: 3) Sefial (signal). En algunos textos, se utilizan las notaciones P y ¥ para las operaciones de espera y sefial respectivamente, ya que ésta fue la notacién empleada originalmente por Dijkstra para referirse a las operaciones’, Asi pues, un semiiforo binario se puede definir como un tipo de datos especial que sélo puede tomar los valores 0-y 1, con una cola de tareas asociada y con slo tres operaciones para actuar sobre ¢l. Las operaciones primitivas pueden describirse tal como se muestra en la Figura 3.3. Las operaciones son procedimientos que se implementan como acciones indivisibles y por ello la comprobacién y cambio de valor del indicador se efectia de manera real como una sola operacién, lo cual hay que tener presente a la hora de disefiar el planificador de tareas. En sistemas con un tinico procesador bastard simplemente con inhibir las interrupciones durante la ejecucién de las operaciones del seméforo. En los sistemas multiprocesador, sin embargo, este método no funciona ya que las instruceiones de los procesadores se pueden entrelazar de cualquier forma, La solucién esté en utilizar instrucciones especiales hardware, si se Aispone de ellas, 0 en introducir soluciones software como las vistas anteriormente, que ya indicamos, que servian tanto para sistemas uniprocesador como para sistemas multiprocesador. La operacién inicializa se debe llevar a cabo antes de que comience la ejecucién concurrente de los procesos ya que su funcién exclusiva es dar un valor inicial al semaforo. 1. Estos nombres provienen de la primera letra de su nombre en holandés: proberen (comprobar) y verhogen (incrementat). ‘También algunos autores as denominan up y down respectivamente, 114 3 Sincronizacién y comunicacién de procesos ‘operacién de inicializar Iniciatiza($: SemaforoBinaro;v: integer) pone el valor del semsforo Sal valor de ¥ (0.01) operucion de espera operacin de se espera (8) seal (S) iS = then Wa cola de tareas ess acta then S = | clse suspender fa area que hace Ia Hamada ‘se reandar Ia primera tavea de Ta cola Y poner en ta cola de tress de areas Figura 3.3: Operaciones primitivas sobre un semaforo Un proceso que ejecuta la operacién espera y encuentra el seméforo a 1, lo pone a 0 y prosigue su ejecucién, Si el semaforo esté a 0 el proceso queda en estado de espera hasta que se libera el semiforo. Dicho estado se debe considerar como uno mas de los posibles de un proceso. Esto es asi debido a que un proceso en espera de un semaforo no esté en ejecucién ni preparado para pasar a dicho estado puesto que no tiene la CPU ni puede pasar a tenerla mientras que no se lo indique el semAforo. Tampoco es vilido el estado bloqueado, ya que este estado estd pensado para que lo utilicen Ilamadas al sistema operativo para suspender o reactivar ‘un proceso que no tiene por qué tener una conexién con los semaforos. El diagrama de transicién de estados de la Figura 2.1 se puede ampliar con un nuevo estado que denominamos de espera (ver Figura 3.4). Cuando se ejecuta la operacién seftal puede haber varios procesos en la lista 0 cola, el proceso que la dejara para pasar al estado preparado dependerd del esquema de gestidn de la cola de tareas suspendidas que se haya implementado en el diseiio del semaforo, por ejemplo: prioridades, FIFO, etc. Si no hay ningin proceso en espera del semaforo este se deja libre (S:= 1) para el primero que lo requiera, Quizés el nombre de espera puede no resultar muy adecuado, ya que ésta slo se producira si el semaforo tiene el valor cero, por ello podria resultar més afortunado é1 nombre de bloqueo o seguro para describir més fielmente la funcién que realiza la operacién, ya que el examen del indicador seftala si la entrada esta bloqueada o asegurada, La lista de procesos suspendidos en espera de un seméforo puede realizarse como una cola de BCP, de forma similar a como se indicé en la Seccién 2-5, de modo que el semaforo mantiene un campo con el valor de este y campos que apuntan a la cabeza y al final de la cola, 3:2Semaforos 115 planifcador expropiado | Nal sf oD 321 Exclusién mutua con semaforos La exclusién mutua se realiza facilmente utilizando seméforos. La operacién de espera se usaré como procedimiento de bloqueo antes de acceder a una seccién critica y la operacién seflal como procedimiento de desbloqueo después de la seccién. Se empleardn tantos semaforos como clases de secciones criticas se establezcan, El proceso P; de la seccién anterior ahora toma la forma: process P1 begin loop espera (S): P*Seccién Critica*/ seal (S); P* resto del proceso */ end end PL; 116 3 Sincronizacién y comunicacién de procesos eS 3.2.2 Ejemplo5 El ejemplo muestra un esquema del comportamiento de una cola ligada a un seméforo utilizado para compartir un recurso entre tres procesos concurrentes (P), P, Ps) En la implementacién de la cola se usa una estrategia FIFO. Se emplea el nombre Acceso/mpresora para designar al seméforo. Tras indicarse la ejecucién de una funcién del seméforo se muestra el estado de la cola ligada al mismo. 1) Inicializa (Accesolmpresora, 1) Accesolmpresora valor= 1 eabecera Se inicializa el semaforo Accesolmpresora con el valor 1 de modo que deja libre el acceso a la impresora. 2) Proceso P, ejecuta: espera (Accesolmpresora) Accesolmpresora valor=0 abecera El proceso P; toma la impresora ¢ impide el acceso de otro proceso al poner a 0 el valor del seméforo. 3) Proceso P; bloqueado, Proceso P; ejecuta: espera (Accesolmpresora) Accesolmpresora valo aes abecera cola =a El proceso P2 intenta acceder al recurso y se suspende, en espera de que éste quede libre, colocindose en la cola del semaforo. 3.2Semaforos 117 4) Proceso P3 ejecuta: espera (Accesolmpresora) Accesolmpresora valor =O) > pia Pe id: Py aber cola El proceso P3 intenta acceder al recurso, se suspende y se afiade a la cola de espera. 5) Proceso Py ejecut: sefial (Accesolmpresora) Accesolmpresora val re cabocera cola m3 =a El proceso P; deja el recurso; el proceso P2 pasa al estado preparado y tomari el recurso cuando pase a ejecucién, 6) Proceso P ejecuta: sefial (Accesolmpresora) Accesolmpresora cabecers cola El proceso P; deja el recurso; el proceso P3 pasa al estado preparado. 7) Proceso P3 €} ecuta: sefial (AccesoImpresora) Accesolmpresora El proceso P deja el recurso, La impresora esti disponible para cualquier proceso. 32.3 Sincronizacién El.uso de semaforos hace que se pueda programar ficilmente la sincronizacién entre dos tareas. En este caso las operaciones de espera y de sefial no se utilizan dentro del mismo proceso sino en procesos separados; el que ejecuta la operacidn de espera queda bloqueado hasta que el otro proceso ejecuta la operacién de sefial 18 3 Sincronizacién y comunicacién de procesos ‘A veces se emplea la palabra seftal para denominar un seméforo que se usa para sineronizar procesos. En este caso una sefial tiene dos operaciones: espera y seftal que utilizan para sincronizarse dos procesos distintos Supongamos que un proceso quiere que se le notifique que ha tenido lugar un suceso determinado y que otro proceso es capaz de detectar que ha ocurrido dicho suceso; el ejemplo siguiente muestra como se puede efectuar una sineronizacién entre los dos procesos utilizando un seméforo, — 3.2.4 Ejemplo6 /* Sincronizacién con sematoro*/ program/module Sincronizacién; var sinero: semaforo: process PI /* Proceso que espera */ begin espera (sincro); end Pl; process P2_/* Proceso que seftala *! begin sefial (sincro end P2; begin /* Sincronizaci6n*/ inicializa (sincro, 0); cobegin PL; P2; coend end Sincronizacion: El semniforo se inicializa a cero de modo que cuando el proceso P; ejecuta la operacién de espera se suspende hasta que el proceso P2 ejecuta la operacidn sefial. La sincronizacién se realiza perfectamente incluso si el proceso Py ejecuta la operacién sefial antes de que el proceso P; ejecute la operacién de espera, ya que en este caso el proceso Ps incrementa el semaforo y permite que P; lo decremente y siga su ejecucion cuando aleanza la operacién de espera. 3:2Semaforos 119 El ejemplo que sigue muestra la solucién que la utilizacién de semaforos oftece al clasico problema del productor-consumidor. Este problema aparece en distintos lugares de un sistema operativo y caracteriza a aquellas situaciones en las que existe un conjunto de procesos que producen informacién que otros procesos endo diferentes las velocidades de produccién y consumo de la informacién, Este desajuste en las velocidades, hace necesario que se establezca una sineronizacién entre los procesos de manera que la informacién no se pierda ni se duplique, consumiéndose en el orden en que se produce. emer 325 Ejemplo7 Suponemos que se tienen dos procesos P; y P3 con las siguientes caracteristicas: 1) P, produce unos datos que consume P> 2) P; almacena datos en algiin sitio hasta que P2 esta listo para usarlos. Por ejemplo, P; genera informacién con destino a una impresora y P) es el proceso gestor de la impresora que se encarga de imprimirlos. 3) Para almacenar los datos se dispone de un buffer 0 zona de memoria comin al productor y al consumidor. Se supone que para almacenar y tomar datos se dispone de las funciones Poner (x) y Tomar (x). Para saber el estado del buffer se usan las funciones Lleno, que devuelve el valor true si el buffer esta lleno, y Vacio, que devuelve el valor true si el buffer esti vacio. El productor y el consumidor corren a velocidades distintas, de modo que si el consumidor opera lentamente y el buffer esta Meno, el productor debera bloquearse en espera de que haya sitio para dejar mas datos; por el contrario, si es el productor el que actiia lentamente, el consumidor deberd bloquearse si el buffer esta vacio en espera de nuevos datos. El programa que sigue muestra un intento de solucién sin utilizar seméforos. /*Problema del Productor-Consumidor: Solucién 1*/ program/module Productor_Consumidor, var BufferComun: buffer; process Productor; var x: dato: begin loop produce (x): while Lleno do espera */ end; Poner (x); end end Productor; 120 3 Sincronizacién y comunicacién de procesos Process Consumidor; var x: dato; begin Joop while Vacio do P* espera */ end ‘Tomar (x); Consume (x): end end Consumidor; begin cobegin Productor; Consumidor; coend end Productor_Consumidor, El productor espera en un bucle hasta que el buffer no esté Ileno y pueda poner el dato x; el consumidor también espera en un bucle a que el buffer no esté vacio y pueda tomar un dato. La solucién no es satisfactoria por las razones siguientes: a) Las funciones Poner{x) y Tomar(x) utilizan el mismo buffer, lo que plantea el problema de la exclusién mutua, al ser ésta una variable compartida. b) Ambos procesos utitizan una espera ocupada, espera activa, cuando no pueden acceder al butler Porque éste esté Ileno 0 vacto. El primer problema puede resolverse utilizando un seméforo para proteger el acceso al butter y ef segundo sineronizando Ia actividad de los dos procesos también mediante el uso de semaforos En la solucién que a continuacién se bosqueja!, se utiliza el semaforo AccesoBuffer para resolver el problema de la exclusién mutua en el acceso al buffer y los semaforos Nolleno y Novacio para la sineronizacin entre los dos procesos. /*Problema del Productor-Consumidor: Solucién con Seméforos*/ program/module Productor_Consumidor; var BufferComun: buffer; AccesoBuffer, Nolleno, Novacio: semaforo: 1. Una solucién completa al caso del productor-consumidor se encuentra en la seecién de problemas. 3:2Semaforos process Productor: var x: dato; begin loop produce (x); espera (AccesoBuffer); ifLleno then sefial (AccesoBufter); espera (Nolleno): espera (AccesoBuffer) ends Poner (x); sefial (Novacio); end end Productor; process Consumidor: var x: dato; begin loop espera (AccesoButfer); if Vacio then seftal (AccesoButter); espera (Novacio); espera (AccesoBuffer): end; Tomar (x): sefial (AccesoButlfer): sefial (Nolleno); Consume (x); end end Consumidor; esi inicializa (AccesoBuffer, 1): inicializa (Nolleno, 1); jaliza (Novacio, 0); cobegin Productor; Consumidor coend end Productor_Consumidor; 121 122 3 Sincronizacién y comunicacién de procesos En la solucién presentada, el acceso al buffer para tomar o poner un dato esti protegido por las operaciones espera y sefial del semaiforo AccesoBuffer. Antes de ejecutar las operaciones espera (Nolleno) y espera (Novacio) se libera el seméforo AccesoBuffer para evitar que se bloquee el sistema. Esto puede ‘ocurrir si, por ejemplo, el productor obtiene el acceso al buffer y permanece en espera de que éste no esté eno para poner un dato, ala vez que el consumidor no puede acceder al buffer por tener el productor y, por lo tanto, también queda en espera de ganar el acceso no pudiendo sacar del estado de lleno al buffer. 3.2.6 Version mas general de los semaforos El seméforo binario resulta adecuado cuando hay que proteger un recurso que pueden compartir varios procesos, pero cuando lo que hay que proteger es un conjunto de recursos similares, se puede usar una versién mis general del concepto de semaforo que Heve la cuenta del ntimero de recursos disponibles. En este caso el semaforo s¢ inicializa con el ntimero total de recursos disponibles (n) y las operaciones de espera urso protegido por el seméforo cuando el valor de y sefial se disefian de modo que se impida el acceso al r éste es menor o igual que cero. Cada vez que se solicita y obtiene un recurso, el seméforo se decrementa y se inerementa cuando se libera uno de ellos. Si la operacién de espera se ejecuta cuando el seméforo tiene un valor menor que 1, el proceso debe quedar en espera de que la ¢jecucién de una operacién sefal libere alguno de los recursos. ‘operaciones pueden describirse tal como se muestra en la Figura 3.5. ‘operaciin de inicalizar Inicialia (S: SemaforoGeners Ve lnteger) poner el valor del seméforo $ al valor de v (a ‘numero_suspendidos operacion de espera espera (S) ‘tS >0then=S~1 se numero _supendidos ‘= numero_supendidos + | suspender la tarea que hace le amads ¥ poner en ls cola de tteas ‘operacién de se sefial (S) It numero. suspends > 0 then numero_supendidos = numero. supendigos~ | pasa l estado preparado un proceso suspendide: ees =5+1 Figura3.S: Operaciones primitivas sobre un semiforo generalizado 3:2 Semaforos 123 Al igual que en los semaforos binarios, la ejecucién de las operaciones son indivisibles, esto es, una vez que se ha empezado la ejecucién de uno de estos procedimientos se continuara hasta que la operacidn se haya completado, Si el semaforo se asocia a un cédigo coneurrente, su valor inicial restringe el nimero méximo de ejecuciones concurrentes que se pueden realizar. Si el valor inicial es 0, ningiin proceso conseguird entrar; si ¢s I, un solo proceso conseguira entrar (por lo que se consigue Ia exclusion mutu); para valores mayores que | se pueden realizar tantas ejecuciones concurrentes del cédigo como indique dicho numero. 124 3 Sincronizacién y comunicacién de procesos Monitores ‘Un monitor es un conjunto de procedimientos que proporciona el acceso con exclusién mutua a un recurso 0 conjunto de recursos (datos o dispositivos) compartidos por un grupo de procesos. Los procedimientos van encapsulados dentro de un médulo que tiene la propiedad especial de que sélo un proceso puede estar activo cada vez para ejecutar un procedimiento del monitor. El monitor se puede ver como una valla alrededor del recurso (o recursos), de modo que los procesos que quieran utilizarlo deben entrar dentro de ella, pero en la forma que impone el monitor, Muchos procesos pueden querer entrar en distintos instantes de tiempo, pero sélo se permite que entre un proceso cada vez, debiéndose esperar a que salga el que esté dentro antes de que otro pueda entrar. En la Figura 3.6 se da un ejemplo de un monitor con dos procedimientos para acceder a los datos: EscribeDatos y LeeDatos; estos procedimientos representan las puertas por las que se puede acceder. El ‘monitor impide cualquier otra forma de acceso al recurso, pero lo que verdaderamente resulta clave, es que sélo un procedimiento puede estar activo cada vez. Si un proceso desea usar el recurso, por ejemplo para escribir datos, llama a EscribeDatos y si no existe otro proceso que esté ya accediendo al monitor, se le permite la entrada para escribir nuevos datos. Si existe otro proceso que esti usando EscribeDatos 0 LeeDatos entonces el proceso que intenta acceder se para y se suspende la entrada en espera de que salga el que esti dentro. FP. tserivepares LeeDaros Figura 3.6: Monitor sencillo La Figura 3.7 muestra un monitor més complejo que el anterior. Ahora se tienen tres puntos de entrada 0 procedimientos para el uso del recurso: Entrada 1, Entrada 2 y Entrada 3, asi como dos condiciones para proporcionar sincronizacién entre los procesos que estin esperando a usar el recurso: condicién A y 3-3 Monitores, 125 condicién B. En la Figura 3.7 el proceso P3 esta usando el monitor y tres procesos estan esperando a entrar: dos en la Entrada | (Py y P2) y uno en la Entrada 3 (Ps). Dos procesos han entrado con anterioridad y se han suspendido esperando la condici6n A (Py y Pg). No hay procesos esperando en la Entrada 2 ni en la condicion B. Realmente, la espera de los procesos para acceder a uno de los procedimientos del monitor no se hace en colas separadas para cada procedimiento, sino que se utiliza una tinica cola para la espera de los procesos que desean acceder al monitor ya que como se ha dicho, slo un procedimiento puede ejecutarse cada ver. P,P). 3} Fntrada conicin A Espora de rad? * condicién Entrada 3 condiidn B Figura 3.7: Monitor general La ventaja para la exclusién mutua que presenta un monitor frente a los semiforos w otro mecanismo es que ésta esti ahora implicita: la nica accién que debe realizar el programador del proceso que usa un recurso es invocar una entrada del monitor. Si el monitor se ha codificado correctamente no puede utilizarse de forma erronea por un programa de aplicacién que desee usar el recurso. Cosa que no ocurre con los semaforos, donde el programador debe proporcionar la correcta secuencia de operaciones espera y sefial parano bloquear al sistema. Los monitores no proporcionan por si mismos un mecanismo para la sincronizacién de tareas y, por ello, su construccién debe completarse permitiendo, por ejemplo, que se puedan usar seftales para sincronizar los procesos. Asi, para impedir que se pueda producir un bloqueo, un proceso que gane el acceso a un procedimiento del monitor y necesite esperar a una sefial, se suspende y se coloca fuera del monitor para permitir que entre otro proceso; por ello, los procesos Ps y Pe de la Figura 3.7 esperan una condicién situados fuera del monitor. Una variable que se utilice como mecanismo de sincronizacién en un monitor se conoce como variable decondicion. A cada causa diferente por la que un proceso deba esperar se asocia una variable de condicin. Sobre cllas slo se puede actuar con dos procedimientos: espera y seflal. En este caso, cuando un proceso eecuta una operacién de espera se suspende y se coloca en una cola asociada a dicha variable de condicién. La diferencia con el semiforo estriba en que ahora la ejecucién de esta operacién siempre suspende el proceso que la emite, La suspension del proceso hace que se libere la posesién del monitor, lo que permite que entre otro proceso. Cuando un proceso ejecuta una operacién de sefal se libera un proceso suspendido en lacola de la variable de condicién utilizada, Si no hay ningin proceso suspendido en la cola de la variable de condicién invocada la operacién sefial no tiene ningun efecto, El monitor debe usar un sistema de prioridades en la asignacién del recurso que impida que un proceso enespera de lograr entrar se vea postergado indefinidamente por otros procesos nuevos que deseen utilizarto, 126 3 Sincronizacién y comunicacién de procesos 3.3.4 Sintaxis del monitor Lasintaxis de un monitor es como sigue monitor: nombre_monitor; declaracién de los tipos y procedimientos que se importan y exportan: declaracién de las variables locales del monitor; declaracién de las variables de condici6n; procedure Pre! (..); begin ... end; procedure Pre2 ( begin ... end; procedure Pren ( begin... end; begin inicializacién del monitor; end, EI monitor no tiene por qué exportar todos sus procedimientos sino s6lo aquellos que sean piiblicos (puertas de entrada de las Figuras 3.6 y 3.7), manteniendo como privados aquellos a los que sélo pueden aeceder otros procedimientos definidos dentro del monitor. Para indicar los procedimientos de! monitor que se exportan y actiian, por lo tanto, como puertas de entrada al monitor usaremos la sentencia export Prel, Pre2,...., Pren; Se emplea la palabra condieion para definir las variables de condicién del monitor. El cuerpo de! monitor contiene una secuencia de instrucciones de inicializacién que se ejecutan una sola ver.y antes de que se realice alguna llamada a los procedimientos del monitor. Ce eeaeapmeeesersal 3.3.2. Ejemplo8 Tlustramos el uso de un monitor mostrando como se pueden realizar las operaciones de espera y de sefial de tun seméforo binario. Las palabras sespera y ssefal designan a las operaciones de espera y seftal del seméforo, y las palabras espera y sefal las respectivas operaciones del monitor. monitor: semaforo; from condiciones import condicion, espera, seftal; 33 Monitores, 127 export sespera, ssefial; ‘ocupado: boolean; libre: eondicion; procedure sespera (var libre: cone begin if ocupado then espera (libre); end sesperas procedure ssefial (var libre: condi begin ‘ocupado := false: sefial (libre); end ssefals besi cocupado := false; end. Se denomina condiciones a la biblioteca donde se encuentra la definicion de las variables de condicién y de los procedimientos espera y sefial de los monitores. La variable ocupado indica el estado del seméforo. Puesto que su valor inicial es false, el primer proceso que realiza una invocacién a la operacién sespera puede acceder al recurso controlado por el monitor y como la variable ocupado se pone a true, cualquier otto Proceso que ¢jecute la operacidn sespera debe esperar a que se ejecute una operacién ssenal para poder accederal recurso, Cuando esto ocurre, la variable ocupado pasa a tener otra vez el valor false y la condicién libre recibe una seftal, 1o que hace que uno de los procesos que esperan en su cola pase a completar la sjecucién de sesperay pueda acceder al recurso. Ejecuciones sucesivas de ssefial van despertando a procesos que estan en el estado de espera hasta que se vacia la cola de la condicién libre. Cuando no hay ningiin proceso en espera de la variable de condicién la gecucién de ssefial s6lo tiene por efecto poner la variable ocupado a false, lo que permite que el primer proceso que ejecute sespera pueda acceder al recurso. re 333° Ejemplo9 Acontinuacién se muestra un monitor para el empleo del buffer en el problema del productor-consumidor. La manipulacién de la variable compartida se realizara de forma exclusiva por llevarla a cabo dentro de procedimientos del monitor (poner y tomar). La sincronizacion de las acciones de poner y tomar datos del tufferse levari a cabo mediante el uso de variables de condicién (espaciodisponible y itemdisponible). Los procesos productor y consumidor tinicamente deberan invocar a los procedimientos del monitor. 128 3 Sincronizacién y comunicacién de procesos ‘monitor: productor_consumidor; from condiciones import condicion, espera, seftal; export, poner, tomar; const tamaiio var buff: array [0..tamafio ~ 1] of dato; cima, base: 0..tamafio— 1 espaciodisponible, itemdisponible: condicion; numeroenbutfer: integer; procedure poner (var item: dato): begin if numeroenbuffer = tamafio then espera (espaciodisponible); end buff [cima] =item: numeroenbuffer := numeroenbutfer + 1; cima := (cima + 1) mod tamaio; sefial (itemdisponible);, end poners procedure tomar (var item: dato); begin if numeroenbuffer = 0 then espera (itemdisponible); end; item := buff [base] ; numeroenbuffer := numeroenbutfer — 1; base := (base + 1) mod tamaiio: seiial (espaciodisponible): end tomar; begin /* inicializaci6n */ numeroenbutfer := 0: cima :=0; 0; base end. 3-3 Monitores. 129 Un proceso que desce poner un dato en el buffer deberd esperar al monitor en la cola de entrada si esti ocupado. Una vez dentro, si el buffer esté leno se suspenderd cuando cjecute espera (espaciodisponible), colocandose en la cola de esta variable de condicién, La espera durara hasta que la ejecucisn por otro proceso de la operacin seftal del procedimiento tomar deje espacio en el buffer. De forma similar, si un proceso llama a fomar cuando no hay nada en el buffer se suspendera cuando ejecute espera (itemdisponible), colocéndose en la cola de esta variable de condicién. Un proceso que ponga un dato liberaré aun proceso que est suspendido en espera del mismo. 3.3.4 Implementacién de un monitor Pasamos a examinar una posible implementacién de los monitores. Como en cada instante sélo se puede estar «jeeutando un proceso, en cada monitor se utiliza un seméforo (exmut) inicializado a 1, al que se invoca antes de entraral monitor espera (exmut) y después de dejar el monitor sefial (exmut) Por otra parte, supongamos que un proceso P; esté utilizando el monitor y ejecuta la operacién seftal (cond) con la variable de condicién condi y que hay un proceso P; en espera en la cola asociada a condi: al proceso P) se le permite ya reanudar su ejecucién, por lo que caben tres posibilidades: 1) Una operacién seftal solo se permite como la tiltima accidn de un proceso antes de dejar el monitor mplos anteriores). (que fue como se procedid en los dos ej 2) Continda el proceso que emite la sefial hasta que acaba con el procedimiento monitor o espera en otra condicién, 3) Continia el proceso desbloqueado por la sefial y el proceso que la emite espera a que aquél acabe con el uso del monitor o a que se suspenda en una condicién En el iltimo caso, para implementar la espera de los procesos seflalados y que puedan reanudar su ejecucién, es posible utilizar un semaforo (siguiente) inicializado a0. Para la ejecucisn en exclusiva de cada procedimiento de entrada al monitor, estos se sustituyen por el siguiente segmento de e6digo: espera(exmut); cuerpo del procedimiento; iffcuenta_siguientes > 0 then sefial (siguiente) else sefial (exmut Se utiliza la variable entera cuenta_siguientes como contador del niimero de procesos suspendidos en la cola del semaforo siguiente. Con esta realizacién, cuando un proceso termina de ejecutar un procedimiento del monitor pasa la posesién de éste a un proceso en espera en la cola del semaforo siguiente; cuando no ha ninguno en la cola de espera de este seméforo, el monitor se pasa a un proceso que espere en la cola del semiforo exmut del monitor. Las operaciones de entrada y salida de! monitor se deben hacer con exclusion mutuaa nivel de hardware para asegurar la integridad de las colas y de las sefales Las variables de condicién se pueden implementar utilizando, para cada una de ellas, un semaforo 130 3 Sincronizacién y comunicacién de procesos binario y una variable entera, ambas inicializadas @ 0. Denominamos scondi al semaforo y scuenta a la variable entera, Las operaciones de espera y sefial del monitor se pueden expresar de la forma siguiente 7° operacién espera de una variable de condici6n: espera(condi)*/ scuenta := scuenta + 1; iffcuenta_siguientes > 0 then sefal (sigui else sefial (exmut); espera (scondi) scuenta := scuenta~ 1; te) /* operaci6n sefial de una variable de condicién: seital(condi) */ if scuenta > 0 then begi cuenta_siguientes := cuenta_siguientes + 1; seiial (scondi): espera (siguiente); cuenta_siguiente end; cuenta_siguientes ~ 1;

You might also like