CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de...

187
I ! i "

Transcript of CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de...

Page 1: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

I !

i

"

Page 2: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

CONTENIDO

PARTE UNO.

ANALISIS DE HERRAMIENTAS PARA LA CONSTRUCCiON DE COMPILADORES.

GENERADORES DE ANALIZADORES LEXICOGRAF'ICOS Y SINTACTICOS.

1. INTRODUCCION.

2. LEX 2.1 ANALISIS DE LEX 2.2 SUMARIO DE LA ESPECIF'ICACION DE ENTRADA. 2.3 LIMITACIONES Y DEFICIENCIAS. 2.4 EJEMPLO LEX: ENTRADA ANALIZADOR LEXICOGRAFICO. 2.5 EJEMPLO LEX: TRADUCTOR 2.6 EJEMPLO LEX: ANALIZADOR LEXICOGRAFICO 11.

3. YACC 3.1 ANALISIS DE YACC 3.2 ESPECIFICACIONES BASICAS. 3.3 ACCIONES. 3.4 ANALIZADOR LEXICO. 3.5 FUNCIONAMIENTO DEL ANALIZADOR SRVTACTICO. 3.6 AMBIGüEDAD Y CONFLICTOS. 3.7 PRECEDENCIAS. 3.8 MANIPUIACION DE ERRORES. 3.9 EL ENTORNO YACC. 3.10 EJEMPLO YACC: GRAMATICA ANALIZADOR

SINTACTICO.

Page 3: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

PARTE DOS

A. PROGRAMACION CONCURRENTE

B. LENGUAJES CONCURRENTES.

A. PROGRAMACION CONCURRENTE.

1. INTRODUCCION.

2. CARACTERISTICAS DE LOS LENGUAJES CONCURRENTES. 2.1 MODULARI[ZACION.

a. PROCESOS. b. PROCEDIMIENTOS c. TIPOS DE DATOS ABSTRACTOS.

2.2 ADMINIST'RACION DE PROCESOS. a. ESPECIFICACION DE PROCESOS. b. DECLAaCION DE PROCESOS. c. CREACION DE PROCESOS. d. TERMINACION DE PROCESOS.

2.3.1 PRIMITIVAS DE EXCLUSION MUTUA. 2.3 SINCRONIZACION DE PROCESOS.

23.1.1 IMPLEMENTACION DE LAS PRIMITIVAS DE EXcLlJSION 1MCJTIJA.

2.3.1.2ALGORITMO DEDEKKER. 2.3.1.3 EXCLUSION MUTUA DE N-PROCESOS.

2.3.2 SEMAFOROS. 2.3.2.1 SINCRONIZACION DE PROCESOS CON SEMAFOROS. 2.3.2.2 LA RELACION PRODUCTOR CONSUMIDOR. 2.3.2.3 SEMAFOROS CONTADORES. 2.3.2.4 IMPLEMENTACION DE SEMAFOROS P Y V.

23.3 REGIONES CRITICAS. 23.4 REGIONES CRITICAS CONDICIONALES. 2.3.4.1 PROBLEMA DEL BUFFER LIMITADO. 2.3.4.2 PROBLEMA DE LOS LECTORES/ESCRITORES 11.

Page 4: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

2.35 MONITORES. 2.3.5.1 EJE3WF"P MONITOR SEMAFORO BINARIO. 2.3.5.2 EJEMPLO MONITOR: LA COMIDA DE FILOSOFOS. 2.3.5.3 IMPLEMENTACION DEL MONITOR. 2.3.5.4 ALGORITMO DE PLANIFICACION.

a. EJECUCION NO DETERMINISTICA. b. COMFILACION SEPARADA. c. SOPORTE A APLICACIONES DE TIEMPO REAL, d. MANEJO DE EXCEPCIONES. e. VERIFICACION DE PROGRAMAS.

2.4. FACILIDADES DEL LENGUAJE.

-

B. LENGUAJES CONCURRENTES.

1. INTRODUCCION.

2. CONCURRENT PASCAL. 2.1 INTRODUCCION. 2.2 ESTRU-RA DE LOS PROGRAMAS DE PASCAL

CONCURRENTE. a. PROCESOS. b. MONITORES. c. CLASES.

2.3 CARPARK PROBLEM. '2.4 MONITORES ANUDADOS.

3. CSP 3.1 INTRODUCCION. 3.2 PROCESOS PRODUCTOR Y CONSUMIDOR 3.3 EJEMPLO: PRODUCTOR-CONSUMIDOR CON BUFFER

LIMITADO.

Page 5: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

4. ADA.

1980. 4.1 EL LENGUAJE DE PROGRAMACION DE LA DECADA DE

4.2 MOTIVACIONES PARA LA MULTITAREA EN ADA. 4.3 EL ENCUENTRO ADA. 4.4 LA PROPOSICION ACCEPT.

4.6 PROPOSICION SELECT. 4.7 EdEMPLO ADA: BUFFER CIRCULAR 4.8 EJEMPLO ADA: LECTORES Y ESCRITORES. 4.9 VERSION DOS DE LECTORES Y ESCRITORES.

4.5 EJEMPLO ADA: RELACION PRODUCTOR-CONSUMIDOR

5. MODULA-2 5.1 INTRODUCCION. 5.2 PROCESOS Y CORRUTINAS. 5.3 EJEMPLO: PRODUCTORES-CONSUMIDORES. 5.4 CORRUTINAS. 5.5 IMPLEMENTACION DE PROCESOS COMO CORRUTINAS.

6. C* CONCURRENTE. 6.1 INTRODUCCION. 6.2 DISEÑO DEL LENGUAJE C* CONCURRENTE. 6 3 CARACTERISTICAS DE C* CONCURRENTE. 6.4 EJEMPLOS.

6.4.1 SEMAFOROS. 6.4.2 RECIPIENTE DE MENSAJES. 6.4.3 ADMINISTRADOR DE TAREAS. ~6.4.4LECTORES-ESCRITORES. 6.4.5 LOS FILOSOFOS. 6.4.6 ORDENACION DE UN ARREGLO. 6.4.7 CONSTRUCCION DINAMICA DE PROCESOS. 6.4.8 TRAYECTORIAS. 6.4.9 PRODUCTOWCONSUMIDOR.

Page 6: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

7. C CONCURRENTE. 7.1 INTRODUCCION. 7.2 EJEMPLO: PRODUCTOR/CONSUMIDOR 7.3 COMPARACION ENTRE C++ CONCURRENTE Y C

CONCURRENTE. 7.3.1 MODELO DE PROGRAMACION. 7.3.2 SEGURIDAD. 7.3.3 COMPLEJIDAD. 7.3.4 EXPRESIVIDAD. 7.3.5 EFICIENCIA.

Page 7: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro
Page 8: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

ANALISIS DE HERRAMIENTAS PARA LA

CONSTRUCCION DE COMPILADORES.

GENERADORES DE ANALIZADORES

LEXICOGRÁFICOS Y SINTÁCTICOS.

Page 9: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

1. INTRODUCC16N.

La h c i o n de un cornpilador consiste en traducir un programa escrito en un lenguaje (hate) a un lenguaje diferente (lenguaje objeto). Debido a que este proceso de traducción es muy dificil, se ha encontrado conveniente dividir un compilador en varias fases: adlisis l&ico9 anlilzsis sintktico, andisis semintico, manejo de errores, manejo de la tabla de símbolos, generacidn de cddigo intermedio y generacidn de cddigo objeto. Cada una de las fases del compilador constituye un problema complicado cuya solución requiere de un programa relativamente grande y complejo.

La creación de nuevos lenguajes de programación y el surgimiento de nuevos procesadores, son factores que hacen de la tarea de escribir cornpiladores un proceso que se realiza con cierta fiecuencia Debido a que un compilador es un programa muy largo cuya construcción requiere de una gran cantidad de tiempo y trabajo, desde hace tiempo se ha buscado desarrollar tknicas y crear herramientas que simplifiquen la construccih de las diversas fases de un cornpilador.

Las herramientas que fditan la construcción de un cornpilador se pueden clasrficar depen&endo la fase del cornpilador que se vaya a construir, asi, para construir el Analizador Sintáctico, existen generadores de Analizadores Sintácticos; para la construcción de una Analizador kcográfico, existen generadores de Analizadores k c o s ; &c.

Por lo anterior, en esta parte se analizan éstas herramientas que fditan la construcción de un cornpilador:

Generador de Analizador Lexicogrkfico: LEX:

Generador de Analizador Sintáctico: YACC.

Page 10: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

2. L E X.

2-1. Análisis de LEX.

LEX es un generador de prograrnas capaces de realizar el procesamiento l&co de archivos de texto, es decir, que pueden reconocer ciertos patrones dentro del conjunto de caracteres que forman parte de un archivo de texto y realizar manipulaciones sobre tales cadenas.

LEX recibe como entrada un conjunto de expresiones regulares y produce como salida un programa capaz de reconocer dentro de un archivo de caractems las secuencias de símbolos que forman cadenas pertenecientes al lenguaje denotado por cada expresión regular-Cada expresión regular tiene asociado un conjunto de acciones que deben ser realizadas cada vez que una cadena con la forma indicada por la expresión regular sea encontrada en la cadena

LEX asocia un código numerico a cada token reconocido.

LEX cuenta con una notación propia para indicar l a s expresiones regulares que forman parte de la especificación de entrada. Las acciones asociadas a cada expresión regular se escriben en un lenguaje de prograrnación de propósito general, de manera tal que el usuario de LEX tiene gran libertad para indicar el procesamiento que debe realizarse sobre l a s cadenas del archivo de entrada

La notación empleada en LEX para indicar la s expresiones regulares no constituye un lenguaje completo, pero puede verse como una extensión que puede ser agregada a &faentes lenguajes de programación denominados lenmes anfitrión. LEX puede producir como salida programas en diferentes lenguajes anfitrión; el lenguaje anfitriitn es empleado tanto para escribir el cbdigo generado por LEX, como los hgmentos de &digo con que el usuario especifica las acciones asociadas a cada expresiitn regular. LEX cuenta con bibliotecas compatibles con l a s distintas implernentaciones de los lenguajes anfitrión soportados, lo cual lo vuelve adaptable a diferentes ambientes y distintos. usuarios. Los imguajes anfitrión actualmente soportados por LEX son C Y . RATFOR.

Page 11: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

LEX transforma l a s expresiones regulares y acciones proporcionadas por el usuario (especificación de entrada) en un programa escrito en el lenguaje &triÓn, en nuestro caso C, denominado yy2ex.c. Dicho programa reconoce l a s cadenas que tienen la forma indicada por l a s expresiones regulares y ejecuta las acciones espec%cadas para cada expresilvn conforme tales cadenas son detectadas en la entrada

LEX puede ser usado sólo para transformaciones sencillas. o para andisis y estadísticas que involucren únimente el nivel Ikxico. LEX también puede emplearse en conjunción con un generador de analizadores sintkticos para efectuar la fase de análisis l é x i c o ; es particularmente sencillo vincular LEX y YACC. Los programas de LEX reconocen únicamente expresiones regulares; YACC genera analizadores sintácticos que aceptan una amplia clase de gramáticas independientes del contexto, pero requiere un analizador de menor nivel para el reconocimiento de los tokens de entrada. De este modo, la combinacicjn de LExy YACC es apropiada

Cuando se utiliza como preprocesador para un generador de analizadores sintkticos, LEX es empleado para partir la entrada y el analizador sintáctico da estructura a l a s piezas resultantes. Otros programas, ya sea emitidos por algún otro genedor o bien escritos a mano, pueden ser agregados fkilmente a los programas generados por LEX:

LEX genera un autómata finito determinístico para l a s expresiones regulares indicadas en la especificación de entrada, el autómata es interpretado, en l u g a r de compilado, con la finalidad de reducir su consumo de memoria, el resultado es un analizador aún suficientemente rápido. En particular, el tiempo requerido por un programa generado por LEX para reconocer y partir la entrada es proporcional d tamaño de la misma.

El nimero de reglas de L l X o la complejidad de l a s mismas, no innuyen de manera importante en la velocidad en que trabaje, a menos que l a s reglas impliquen contexto adelantado que requiera una cantidad significativa de anhlisis repetitivo de la entrada Lo que crece con la complejidad y cantidad de l a s reglas es el t m d o del autómata finito, y en consecuencia, del programa creado por LEX

Page 12: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

En el programa generado por LEX los fragmentos de &&go que el usuario proporciona como acciones para ser ejecutadas cuando se encuentren cadenas que tengan la forma indicada por la expresión regular asociada, son codificados como cases dentro de un switch 6 el caso de C, o como ram& de un GOT0 computado en RQTFOR.

LEY; como ya se &joy acepta como especdicación de entrada expresiones regulares, esta especificación de entrada debe ' de tener cierto formato para que puede ser bien interpretada por LEX. el formato general de la especificación de entrada debe ser de la forma:

defuuciones %Yo reglas %Yo funciones del usuario.

LEX transforma las reglas en un programa Cualquier línea que no sea parte de una regla de LEX ó una accion y que inicie con un blanco o tabulador será copiada al programa generado por LEX. Todo lo que aparezca con estas características antes del primer %% será externo a toda fúnción dentro del código. Si aparece inmediatamente después del primer %%, será incluido en el lugar adecuado para las declaraciones en la función generada por LEX en que aparecen las acciones. Las líneas que contengan un comentario, o que inicien con un blanco 6 tabulador, serh pasadas directamente al programa generado. Cualquier texto incluido entre una pareja de líneas que contengan únicamente %{y %] respectivamente, será copiado al programa generado (excluyendo desde luego, los delimitadores). Este formato permite incluir por ejemplo directivas al preprocesador (#&?ne, #include) que deben iniciar en la columna uno, o incluir un número ilimitado de líneas.

Cualquier texto después del izltimo %% es copiado al final del programa generado por LEX sin importar el formato.

Page 13: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

\

Un ejemplo de una especificación para LEX en la cual se muestra un conjunto abreviado de reglas para reconocer números:

D [O-91 E [DEde][-+]?(Dl+ %Yo (DI+ printf(ffentero."); (D)+"." (Dl*( (E))? 1 (D)*"."(D)+((E))? I (D)+ (E) printf("real.");

Así, la forma de la especificación de entrada guarda' un estricto formato que de ninguna manera puede ser cambiado, en caso de que se especifique de otra manera, LEX no puede realizar su trabajo, así que el formato para la especificación dada debe' guardar siempre esta estructura, para lograr que el analizador lexicográfico realice bien su trabajo. No es posible que se de en otro orden.

Pero, las dehciones y fhciones son opcionales, el segundo %% es opcional también,' el primer %% se requiere para marcar el inicio de las reglas, asi el programa mhs pequeño que puede escribirse para LEX es:

Las reglas constituyen una tabla, cuya columna izquierda contiene expresiones regulares y la columna derecha contiene acciones, fragmentos de programa que deben ser ejecutados conforme l a s expresiones regulares son reconocidas.

Las acciones son fragmentos de código en lenguaje anfitrión: C, cualquier tipo de &digo es aceptado en esta parte de acciones, dando esto cierta facilidad al realizar el analizador lexicogridico, (como el manejo de la tabla de símbolos, el manejo de errores que resultan al encontrarse un patrón no reconocido por cierta gramática en un lenguaje de programación).

Page 14: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Veamos la forma en que se especifican las expresiones regulares para LEX:

Una de las formas de especificar las expresiones regulares es escribiendo de forma textual la cadena que se desea reconocer, es decir, se escribe la cadena misma que corresponde idénticamente a la que se desea reconocer de la entrada a a n a l i z a r .

Otra forma es haciendo alguna definición de una expresión regular? en la sección de definiciones, esto es, al realizar la definición de alguna clase, por ejemplo:

clase1 [ a-zA-Z]

se incluye la especificación: {clasel) para indicar que cuando se encuentre al@ carácter de la clase, esto es, alguna letra, realice la acción correspondiente. La clase clase1 espedca siempre alguna expresión regular escrita bajo l a s reglas existentes, casi no hay diferencia entre la forma de especificar alguna expresión regular en LEXy la forma en que teóricamente se hace, es decir, la forma en que cualquier texto maneja

Esto da una ventaja enorme al poder escribir la misma expresión regular que se desee en teoría y la forma de hacerlo para LEX, salvo algunas; excepciones en las que la diferencia radica solamente en un cmibio de notación, ya que LEX tiene algunos caracteres especiales denotados como operadores que sirven para la mejor especificación de entrada, y el también alguna diferencia existente en el significado que tienen algunos caracteres dependiendo del contexto en que sean usados, ya que pueden usarse como ya se dijo, en las declaraciones de clases, o en las mismas clases, o en algunas formas de agrupamiento e intervalos, y alternativas que LEX también maneja

A continuacih se dan algunos ejemplos de expresiones regulares que LEXacepta como especificacih de entrada:

[1 A-Za-z] [A-Za-zO-9]* =

Indica todas las cadenas que inician con una letra y son seguidas por cualquier número de letras y\o dígitos. (identificadores).

Page 15: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

[*abc] =

Representa todos los wacteres excepto a,b y c.

[-+o-91 - -

Coincide con todos los digitos y ambos signos.

Coincide tanto con la cadena ab como con cd. i

Otra ventaja que caracteriza a LEX es su reconocimiento de contexto en tomo a l a s cadenas, esto es, LEX es sensible al contexto. Expresiones de

caracteres al principio o al final de éstas, o solamente si se encuentran al principio o find de alguna línea, esto es, contexto por la derecha y cuntexto por la izquierda; también se reconocen ciertas cadenas si se encuentran seguidas por alguna cadena o preuxhdas por otra Esto es la forma de especificar condiciones para el reconocimiento de cadenas o patrones de la entrada que se reconocerá

I la entrada pueden ser reconocidas solamente si contienen ciertos

Como ya se menciono, LEX permite insertar en su especdicacion miones que ejecuta cuando encuentra una cadena que coincide con alguna de las expresiones regulares indicadas en la especificación de entrada de LEX, una acción por omisión es copiar la entrada a la salida; esto se ejecuta para todas l a s cadenas que no coincidan con ninguna de las expresiones regulares espedcadas.

Otro manejo importante que realiza LEX es la ventaja de contar con algunas variables que maneja, en las cuales ab momento de reconocer alguna cadena de la entrada se copian valores que facilitan la ejecución de las acciones correspondxmtes, algunas - de estas variables son:

2 - wtext : variable que contiene la cadena que coincibb con una cierta expresion regular, es global, sirve, entre otras cosas, para imprimir en la sahda la cadena identificada

Page 16: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

VyZeng : contiene el número de caracteres de la cadena que se acaba de reconocer.

También LEX cuenta con funciones d e t e d a s que ayudan, como se dijo, al mejor manejo de las acciones:

yymoreo :, que al ser invocada provoca que la siguiente expresibn reconocida sea concatenada a la contenida en yytext.

wZess(n) : al ser invocada provoca que n caracteres de wtext sean retenidos y los caracteres restantes sean devueltos a la entrada.

Esto proporciona el tipo mencionado de análisis adelantado del contexto por la derecha pero en una forma controlada por el usuario.

input0 : que devuelve el siguiente carácter de la entrada

outputo : que escribe el carácter en la salida.

unput(c) : que devuelve el carácter c a la entrada para ser leído más tarde por inputo.

yywrapo : la cual es llamada siempre que LEX encuentra el fin de archlvo. Si w u p o devuelve el valor 1, LEX considera terminada la entrada

La axiiin W E C T sipfica "intenta con la siguiente alternativatt; esta provoca que se considere una segunda regla despuh de la ejecutada en primer instancia, ajustando el apuntador de entrada a una posici6n adecuada

Como se puede observar? las ventajas de tener funciones propias para el manejo de la.. acciones y del análisis es relevante, ya que se puede tener una visión mejor de lo que se va reconociendo, al no hacerlo a ciegas; pero también se pueden efectuar métodos de reconocimiento más sofisticados que el simple reconocimiento de cadena p,or cadma, d poder reprocesar texto en la forma deseada, en diversas círcunstamias.

Page 17: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

LEX puede manejar especificaciones ambiguas. Cuando más de una expresión coincide con la entrada vigente, LEX selecciona alguna de ellas en la siguiente forma:

1. ~a expresión cuya coincidencia implica una cadena de mayor longitud es preferida

2. Si no es posible elegir por longitud, se prefiere la regla que se haya especificado primero.

La. forma en que LEY se usa para generar el analizador lexicogdfíco es (incluyendo el programa en C):

El proceso consta de dos pasos para la compilacih de un programa firente de L m primero, la especificación de entrada de LEX debe ser transformada en un programa generado para el lengqe anfitrión elegido, C, esto se logra escribiendo en la linea de comando:

l e x <archivo> donde <arch~vo> tiene la especificación de entrada

después el programa generado debe ser compilado y ligado con una biblioteca de subrutinas de LEX El programa generado queda en un archivo denominado 2eyy.c en la computadora

De esta forma se analiza de manera concreta la forma en que LEXse debe usar y sus caracteristicas más importantes que lo hacen destacar entre los generadores de analizadores lexicográficos.

Page 18: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

2.2 Sumario de l a especif icacidn de entrada.

A continuación se da un sumario de la especificación de entrada:

Formato general:

definiciones oiao/o reglas %% funciones del usuario.

La sección de definiciones contiene una combinación de:

1. Definiciones de la forma :

nombre expresión

2. C M g o incluido, precedido por al menos un espacio o tabulador.

3, Código incluido en Ia forma :

4. Condiciones de inicio con el formato :

%S nombre1 nombre2 . ._

5. Tablas de conjunto de caracteres de la forma :

%T numero carácter %T

6 Una especificacih de lenguaje que debe preceder a todas las regIas o códrgo incluido: %C para C, o bien YoR para K4TFOR

Page 19: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

7, Cambios a los tamaños de los arreglos internos de la forma :

donde nnn es un entero (en base diez) representando el tamaño del arreglo, y x representa alguno de los siguientes parámetros:

P posiciones n estados e nodos de árbol a transiciones k clases de caracteres O tamaño del arreglo de salida

En la sección de reglas, l a s heas tienen el formato:

expresih acción

donde ambos elementos son opcionales (si sirlo hay acción, ésta debe ir precedida al menos por un blanco o tabulador). Las acciones que requieran más de un renglbn, deberán encerrarse entre llaves.

Las expresiones regulares de LEX emplean los siguientes operadores:

X la cadena x. "X" la cadena x, a h cuando contenga operadores. \x el canicter x, aim cuando se trate de un operador. [xy] el &ter x o el caaacter y. [a-z] los caracteres a,b,c,d,e,. . .,z. [ Ax-z] todos los caracteres excepto x,y,. . . ,z.

^X la expresión x al inicio de la línea.

X$ la expresión x al final de una línea. X? la expresión x opcionalmente.

todos los caracteres excepto el de nueva línea

<y)x la expresión x si la condición y se encuentra activa

~

!

Page 20: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

x* cero o más ocurrencias de x. X+ una o más ocurrencias de x. xb la expresión x o la expresibn y. (x) la expresibn x. x/y la expresicin x, cuando sea seguida de la expresión y. (x) la traducción que le corresponde al nombre x. x(m,n) de m a n ocurrencias de x.

2 . 3 , L i m i t a c i o n e s y d e f i c i e n c i a s .

Hay expresiones patológicas que producen un crecimiento exponencial de las tablas cuando se les transforma en un autómata determinístico; afortunadamente son poco fiecuentes.

REIECTno reanaliza la entrad& en lugar de esto, "recuerda" el resultado de la última cadena analizada Esto significa que una regla que involucre contexto adelantado y que emplee REJECT no fimciond adecuadamente si el usuario empleo unput para cambiar los caracteres leidos adelantadamente. Esta es la única restricción impuesta para la manipulación de entrada no procesada.

2 . 4 , E j e m p l o LEX: E s p e c i f i c a c i c j n p a r a un A n a l i z a d o r . Lexi cográ f i co . % {

/*""-- -

Especificación de Entrada de LEX. Para el Analdor Lexicográfíco.

I

_I__-__ -___.-___1 " S*/

#include<alloc.h> #incIude<string. h> #include<math.h> #include<ctype. h> #include<stdio. h> #include<conio. h>

Page 21: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

#include<stdlib.h> #define MM-SIM 47

/* funcibn principal */ main(char *argv[])

FILE *entrada, entrada = fopen(argv[ I], 9"'); yyin = entrada; ifi&ym ==NULL) fprintf(stdout, "Error, no se encontró el archrvo : %S .h", argv[lI);

else l Visualiza Mensaje(); Ve Encabezadoso; I~~ializa_Tabla(&Tabla_Simbolos); Inserta-Rservadas(&Tabla-Shbolos); while@ylex())

7

printf("bbhl Análisis Concluido ...'I); getcho; fclose(yym); Visualiza_Tabla(Tabla-Simbolas); 1

1 /* fin programa */

Page 22: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

c

YO96 int tipotoken = O; char caract = ";

(Idatif) ( tipotoken = Investiga(jytext, 1);

retum(tip0token); 1

(Cadenas) ( tipotoken = InvestigaQytext, O);

retum(2); 1

(Comentario) { c m t = input(); caract = toupper(caract); /* acción sólo para evitar error de compilación */ /* se lee un carácter para que se reconozca el comentario mdtilinea. */

1 (Caracter) {

retum(3); 1

(Numentero) { (Delim) ;

re;Wn(4); 1

(oparitm&co) { switch(wtext[0])

case '+' : r-( 12); case '-' : return( 13); case '*' : return( 14); case '/( : retum(15); 1 1

(Qplogico1 ( iq!(s~~p(yytext,"&~\~"))) { return(l6); )

Page 23: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

I

if(! (strcmp~yytext,"IJ\O"))) { return( 17);

ifl!(strcmp(yytext, "!\O")))

return( 1 8); 1 1

V w d @ if(! (strcmp(jytext? *'=\O''))]

retum(l9); 1 iq! (strcmp(yytext, ">=\O"))) {

1 retum(20);

if(!(strcmp(yytext? "<=\O")))

retum(21); 1 ifl! (strcmp(jytext, "!=\O")))

retun(22); 1 1

(Asignacíon) ( retum(23);

1 mPAgnrP1 {

switchoyteext[O]) {

case '(1 : return(24); case '1' : retum(25); ca$e ',' : return(28);

case '(' : return(26); case ';? : retum(29);

Page 24: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

case '1' : retwm(26); 1 1

b t * I

tipotoken = yyleng; m o r a ; Visualiza_Error(yytext, (yyleng - tipotoken)); renglon++; renglon++; 1

%Yo /* frmción que visualiza mensajes en pantalIa */ void Visualiza_Mensaje(void)

clrscr("J; gotoxy(26,6); prin~'ANALEAD0R LEXICWRÁFICO. "); gotoxy(26,8); printf(" Generado por LEX."); getch0; 1

En el ejemplo anterior, la especificacibn de entrada para LEX se him en base a un Analizador Lexicogrkfico que reconoce los siguientes tokens de un archtvo de entrada:

Identificadores, cadenas ( "xxxxx"), caracteres ('B'), comentarios mdtilinea, números enteros ( 1234 ), operadores aritméticos ( +, -, /, *IT operadores 1bgicos ( U, 11, ! )> operadores de orden ( a=- >=, =9 != )?

asignación ( = )7 separadores y agrupadores ( (, ), ;, ,, {, 1.

Tiene l a s tres secciones en que se divide una especificación de entrada, donde en cada una se puede ver d m 0 se pueden utilizar para hacer mhs fácil la especificaciirn.

Page 25: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

YO { I* -

Especificación de Entrada para Lex. Programa : Traductor.

Nota : se sustituyen las palabras sin importar en que contexto e s t é n .

"- _ _ ~ _ _ _ " . _ _ _ I */ #include<stdio. h> #include<conio.h> #include<ctype.h> #include<stdlib.h> #include<dos.h>

/* Variable Global : Archivo-Salida Es de tipo FILE, donde se guarda la salida del programa, es decir, el programa traducido */ FILE *Archivo-Sdida;

/* prototipo de fúncihn usada */ char *Obtiene - NombrHvoid);

/* función principal */ main(char *argv[])

FILE *entrada; char "archivo - salida; entrada = fopen(argv[ 11, 'Y); yyin = entrada; ifolyln = NULL)

printf("hhh ERROR, no se encontró el archivo : %s.",argv[l]); getcho;

else

mchtvo I salida = Obtiene - Nombre();

Page 26: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Archivo Salida = €open(mchmo - salida, "wl'); while(Yylex0)

9

gotoxy(26,6); printf("Traducción terminada 'I); delay(2000); fclose(yylll); fclose(Arckvo_-Salida); 1 1 YO) Si [SS] [ Ii] principal [PPI w - 1 [Iil P n l P I [GI PPI [Aal [Lll Funcion [ FfJ [ Uu] [Nn] [ Cc] [Ii] [ 001 [Nn] Devuelve [Dd][Eie][Vv][Uu][Ek][L1][Vv][Ee] Mientras [Mm][Ii][Ee]fNn][Tt][Rr][Aa][Ss] Entero [Ee][Nn][Tt][Ee][Rr][Oo] om P o l [Ttl c w P o l

Yo% (Si) fprintf(Archiv0 Salida, "if'); (Principal) fprin~(Á&vo-Salida, "main"); (Devuelve) fprintf(Archivo Salida, "return"); (Mientras) fPMtf(Archiv0 Salida, "while"); (Entero) i$ring(Archivo salida, "int"); (Otro) fpMtC(Archivo - <&da, "else"); (Funcion) ; * I \n fpring(Archivo I Salida, "%S", yytext); Yó%

char *Obtiene - Nombre(void)

char "hombre; nombre = (char *) malloc (1 3); clrsc<l; gotoxy(Z6,6); printf1"T R A D U C T O R."); delay(I 500); gotcq(26,8); prinq'Wombre del archivo traducido : )> "1;

(

Page 27: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

I

gotoxy(26,6); printf(("T R A D U G T O R"); delay( 1500); gotoxy(26,8); printQ'Wornbre del archivo traducido : >> "1; gets(nombre); clrscr(); retum(nombre); 1

Este ejemplo lo que hace es leer un archivo fuente y cambiar todas l a s ocurrencias de l a s palabras siguientes por su correspondiente traduccibn y escribir el contenido del archvo en otro archivo pero con las palabras cambiadas, es decir, si el archvo fuente tiene l a s palabras mostradas, el archivo de salida tendrá lo mismo que el €üente, excepto que l a s palabras que se reconocieron aparecerán con su correspondiente traducción:

if

main

return

while

int

else

Page 28: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

2.6. Ejemplo LEX. Analizador Lexicográfico 11.

YO {

/* definiciones de coflstantes para identificar los tokens */

#define IF 1 #define ELSE 2 #define BREAK 3 #define WHILE 4 #define RETURN 5 #define PUNTO COMA 6 #define PAR IZQ 7 #define PARIDER 8 #define LL IZQ 9 #define LLDER 10 #define M& 11 #define MENOS 12 #define POR 13 #define ENTRE 14 #define MAYOR QUE 15 #define MENOR-QUE 16 #define MAYOR-IGUAL I7 #define MENOR-ÍGUAL 18 #define IGUAL 19 #define DISTINTO 20 #define ASIGN 21 #define MASMAS 22 #define MENOSMENOS 23 #define COMA 24 #define ID 25 #define CONST 26 I

#define ERROR 27 #define INT 28 #define PRINT I 29 #define PRDJTIG 30 #define COMILLA 31

-

Page 29: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

int líneas = O ; /* contador de Iineas analizadas */ char ultimo-id[ 201 ; /* buffer para guardar el ultimo

main (int argc, char *argv[J) iden~cador */

FILE *fopen(& char *p; if (argc = 1)

else { fprin@stdout,"falta nombre de archivo bh");

if ((yym = fopen(argv[ l].J"r")) = NULL)

else { fjxin@stdout,"Error al abrir el archivo : %S hb",argv[ 11);

clrscfl; while (p = (char *) yylexo)

prin@"Lineas analizadas: %dh",lineas); fclose(yym);

prinW1%- 1 Od \"%s\"W',p,yytext),yytext);

1 1 1 %) letra [a-zA-Z] digito [o-91

[ \tI finlinea c\n3 letra o digito [a-zA-2 0-91 blanco " -

otro

Yo%

"PRINT C"

"INT" "IF" "ELSE" "BREAK" "WHILE"

~IPRINT-I~~

I1

Page 30: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

!l. I1 Y rehun(PUNT0 COMA);

'I C' retum(PARI2Q); retUrn(PAR-RER);

" rdurn(LL_IzQ); " 1 return(LL DER); W+ll retum(MAs); 11-t1 return(MEN0S); tt*l! retum(P0R);

11/" return(-); ll>ll renun(MAYOR-QUE); tr<tr retum(ME3NOR QUE);

"GE" retum(MAY0R~IGIJAL); "LE" return(MENOR-IGUAL); "EQI return(1GUAL); 'WE" retum@ISTINTO); t1,(1 return(AS1GN); "PP" return(MASMAS); "MIVI" retum(MEiNOSMEN0S);

Y r&um(COhillA); t l t l l return(C0MLLA);

(letra) (letra - 0-digitoy ( strcpy(ultimo-idyyytext);

(&@O)+ return(C0NST);

( O W rehun(ERR0R); (finlines> (ECHO;

t1 I1

returnC1D); 1

(blanco) Y

lineas++; 1

En este an&zador.lexicográfico, se reconocen 10s siguientes tokens:

Las palabras reservadas : IF, ELSE, BREAK, INT, WHILE, RETURN; Identificadores, niuneros; y los caracteres : ;y (y )y (, 1, +y -y *y <, >y >=y

<=. = == <) ++ " 7 Y Y Y 9 -

Page 31: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

3. Y A c c. 3.1. Ana’lisis de Yacc .

Empecemos con una descripcibn de lo que es YACC y como se debe dar la especificacibn de entrada, asi como caracteristicas escenciales:

YACC es un generador de analizadores sintácticos que recibe como entrada una gramática (almacenada en un ar&vo de texto, al que se denominará archivo de especificacibn de entrada para YACC) y produce como salida el analizador sintáctico ascendente que reconoce l a s estructuras definidas por l a s producciones de la gramática; si por alguna d n no es posible crear el analizador sintáctico, YACC envía un mensaje indicando cud es el problema

Para invocar a YACC, desde el sistema operativo se da el comando :

c:> YACC +obre del archivo de especificación de entrad^

si no hubo errores, YACC produce como salida el analizador shtktico(escrito en C)correspondite a

la gramática contenida en el archivo de especificacion de entrada. El analizador sintktico se almacena en un archivo Ilamado ytab.c y la función que debe invocarse’ para realizar el midisis sinttktico de algún programa füente se 1lamayyparseC).

. El usuario debe proporcionar el analizador léxico que reconozca los tokens indicados en los lados derechos de las producciones de la gramhca; este analizador léxico (que debe llamarse ylZex) es invocado por el analizador sintáctico producido por YACC cada vez que se requiere el siguiente token de la entrada

Es posible asociar a d a símbolo no terminal de la gramfica un conjunto de atributos y a cada produccibn un conjunto de acciones semhticas, de forma tal, que el programa producido por YACC pueda realizar otras tareas aparte de l a s propias del analizador sintáctico, tales corno análisis semántico, hterpretacibn, generación de ,&digo, etc. El programa producido por YACC está escrito en C, l a s acciones semánticas también deben escribirse en C.

Page 32: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Las reglas gramddes proporcionadas a YACC deben tener cierto formato para que YACC pueda comprenderlas. Una regla comienza con el símbolo no tennind del lerdo izquierdo de la producción, seguido de dos puntos, el lado derecho de la producción y termina con punto y coma. Una regla gramatid podría ser la siguiente:

fecha : nobre - mes día I,’ aÍí0 ;

donde fecha, nombre mes, dia y año representan símbolos no terminales; fecha es el lado izquierdo de la produccibn, mientras que el fado derecho de la misma es todo lo que aparece después de los dos puntos. La coma entre apostrofés indica que se espera que aparezca literalmente en la entrada. Tanto los dos puntos como el punto y coma son parte de la sintaxis para la regla, funcionando como signos de puntuacion: los dos puntos sirven para separar el lado izquierdo del lado derecho de una praduccibn y el punto y coma señala el find del lado derecho de la misma.

Una parte importante del proceso de entrada es llevada a cabo por el analizador l é x i c o ; esta función, proporcionada a YACC por el usuario, lee la entrada para obtener estructuras elementales y enviarlas al analizador sintáctico. Por razones históricas, una estructura reconocida directamente por el analizador léxico se denomina símbolo terminal, mientras que l a s estructuras reconocidas por el andidor sintáctico son denorrinadas símbolos no terminales.

Es usual referirse a los símbolos termínales como tokens.

En a l p o s casos no es simple decidir a que nivel debe reconocerse un elemento de la entrada: si como token, por medio del analizador léxico, o como regla grmatid a través del analizador sintáctico, esto debe decidme mediante la evaluaci6n de la eficiencia del caso elegido, sin que halla complicaciones para YACC.

Una característica que destaca en YACC es el manejo de errores que soporta como parte de la especificacibn de entrada, ya que permite al analizador sintáctico pedir que se vuelva a proporcionar una parte de la entrada errbnea, o bien continuar el análisis, ignorando la pwte que tenga errores.

Page 33: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

En algunos casos, YACC no logrará producir un analizador sintáctico para una especificación dada; esto podría ocurrir si la especificación fuera contradxtoria; o bien si requiriera un mecanismo de reconocimiento más poderoso que el proporcionado por YAW. El primer caso representa un error de diseño, mientras que el segundo, en muchas ocasiones puede resolverse empleando un analizador l6xico m& poderoso o modificando algunas reglas gramaticales.

Pese a que YACC no es capaz de manejar correctamente todas las especificaciones posibles, su potencial es comparativamente mayor al de sistemas similares; más aún, l a s construcciones que representen dificultades para YACC, son igualmente dificiles de manejar a nivel conceptual. Algunos usuarios han reportado que la hsciplina impuesta por la formdacion de especificaciones vlilidas para YACC, ha revelado errores de concepcion o de diseño en etapas iniciales del desarrollo de programas.

YACC ha sido empleado en numerosas ap1icacíones prácticas, por ejemplo en lint, en el cornpilador transportable de C y en un sistema para tipografia matemática

3.2. Especificaciones ba'sicas.

Un nombre puede denotar tanto un token corno u1 símbolo no terminal, YACC requiere que los nombres para los tokens sean declarados corno t a l e s .

Todo a r h v o de especificación consta de tres secciones:

declaraeiones, reglas gramaticales y hciones del usuario. Las secciones se separan con el delimitador 96%. De manera esquemática, un archivo de especrficacih para YACC tiene el siguiente formato:

declaraciones YOYO reglas gramaticales YO% fimciones del usuario

i

Page 34: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Las secciones de declaraciones y funciones son opcionales, por tanto, el formato de especificadn mínima admisible para YACC es el siguiente:

Yo% reglas

Los espacios en blanco, tabuladores y caracteres de nueva línea son ignorados. Los comentarios que puedan aparecer en cualquier lugar a que un nombre es admisible, son encerrados entre /* y *PI como en C.

La sección de reglas puede contener UAB o mas reglas gramaticales.

Una regla gramatical tiene la forma :

donde LADO - IZQUIERDO representa un no tennind y CUERPO representa una secuencia de cero b más nombres y literales. Los dos puntos y el punto y coma son signos de pwntuación para YACC, el punto y coma es opcional.

Los nombres pueden ser de Iongtud arbitraria y estar formados por letras, puntos, guiones de subrayado y dígitos, estos últimos siempre y cuando no sean el primer caracter del nombre. YACC diferencia las letra maMculas de las minkculas. Los nombres empleados en el cuerpo de una regla gramrttieal pueden representar tanto tokens como símboIos no terminales.

Se puede usar el carmter I cuando hay varias reglas:

A : B C D ; A : E F ; A : G ;

pueden escribirse de la forma

Page 35: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Si algún símbolo no terminal X deriva la cadena vacía, se escribe la regla :

X : ;

Los nombres que representan tokens deben ser declarados, la forma más simple de hacerlo es empleando la directiva %token:

%token nombre1 nombre2 nombre3 . . .

en la sección de declaraciones, YACC asume que todo nombre que no sea declarado en la sección de de"aciones es un símbolo no terminal. Todo símbolo no terminal debe aparecer en el lado izquierdo de cuando menos una regla gramatical.

Entre los símbolos no terminales, hay uno denomitlado símbolo inicial, que es de particular importancia. De no inkcme de otro modo, se asume que el símbolo inicíal es el que aparece en el lado izquierdo de la primera regla @Iramatical; para indicar explícitamente el símbolo inicial, en la sección de declaraciones puede incluirse la declaración :

%start simholo - inicial

E1 final de la entrada al anahador sintáctico debe ser seiialado mediante' un token especial que llamaremos marca de fin. El analizador sintáctico acepta una entrada si, al terminar de formar el &bol de parse de la entrada, recibe del analizador léxico la mrca - de-fin. Si la marca-deJn aparece en cualquier otro contexto, se trata de un error.

"

El analizador léxico incluido en la especificación de entrada para Y A K debe devolver la marca " de fin al encontrar el fin ,de archivo.

3 . 3 . Acciones.

Con cada regla gramatical, el usuario puede asociar acciones que se ejecutan cada vez que la regla es reducida durartte el proceso de análisis; éstas acciones pueden calcular valores y acceder a los valores calculados por acciones previas. Más aún, al valor del atributo asociado a algún token puede utilizarse en dichas acciones.

Page 36: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Una acción es una ínstruccidrn de C y COMO tal puede realizar entrada, salida, llamadas a firnciones o alterar variables globales. Las acciones pueden eonttmer una o varias instrucciones, pero en todos los casos deben encerrarse entre llaves. Por ejemplo,

A : '(1 B '1' { función( 1 ,"abc");

ó bien

son reglas gramaticales con acciones.

Es posible asociar atributos a los sirnbolos no terminales de la gramática y emplear los valores de los atributos en las acciones. El valor del atributo del símbolo no termínal del lado izquierdo de una producción se denota en Y A W mediante la pseudovariable $$.

$1 es el valor del h b u t o del primer símbolo del lado derecho.

$2 es el valor del atributo de1 segundo simbolo del lado derecho.

...

A s í para la produccibn:

A : B C D ;

$2 denota el valor del atributo asociado a C y $3 el valor del atributo del símbolo D.

I !

II i 1 1

Page 37: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

En : a : €3

( $ $ = I ; )

(x-%2;z-%3; ] C

el efecto de las acciones es asignar a x el valor de 1, y a z el valor asociado al símbolo no terminal C.

Las reglas con acciones semiinticas que no se encuentren al final de una regla son modificadas por YACC, quien crea un nuevo símbolo no terminal que derive la cadena vacia y la acción interior es colocada al final de la nueva regla A s í , YACC trata el ejemplo anterior como si én realidad tuviera l a s sipmtes reglas:

NUEVO SIMBOLO : /* cadena vacía *I f $$ = 1; ) ;

A : BNUEVO - SIMBOLO C (x=42;z=$3- > Y 1 -

Por ejemplo la definición :

%( int variable = O; %)

puede colocarse en la sección de declaraciones, haciendo que variable sea accesible a todas las acciones y al analizador Iexico. El a n a l d o r sintáctico generado por Y A K emplea variables globales cuyo nombre cpmienza con el prefijo y y ; el usuario debe evitar nombres que inicien con dicho prefijo.

El usuario debe proporcionar a Y A K un a n d d o r I6xíco que ¡ea Ia entrada y encuentre íos tokens presentes en la misma El analizadoi léxico, COMO ya se dijol es una funcicin llamada vyZex() que devuelve un entero. Al vdur entero devuelto por la hci6n es el &digo del siguiente token. Si se desea devolver un valor adicional asocIdo a dicho token, este puede asignarse a la variable externa llarnadar~lval.

Page 38: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

El analizador sintáctico y el léxico deben asignar los mismos códigos a los tokens para hacer posible la comunicacibn entre ellos. lxts cbdigos pueden ser elegdos por YACC, o por el usuario; en ambos casos, el mecanismo #define de C se utiliza para permitir el uso de constantes simbólicas en lugar de números.

3.5.Funcionamiento del analizadur sint$ctico.

YACC transforma la especificaci6n que el usuario le proporciona en un programa escrito en C; este programa es capaz de analizar la entrada Y

determinar si está formada se@ las producciones indicadas en la especificacibn. El algoritmo empleado para transfonnru la especificxibn de entrada en un analizador sintáctico, es complejo, sin embargo, el analizador sintáctico es relativamente sencillo y la comprensibn de su hcionamiento, es de utilidad para efectos de nuestro anhlisis.

~. El analizador sintáctico que YACC genera se basa en un autómata de pila. Este analizador es capaz de leer y recordar el siguiente token de la entrada (denominado token adeluntudo G loohhead). El atado vigente es siempre el representado en el tope de la pila.. Los estados del autbmata finito se etiquetan con enteros pequeiios; al inicio, el autbmata se encuentra en el estado O, la pila tiene s610 el estado O y no hay token adelantado, ya. que ninguno ha sido leído.

El automata cuenta con cuatro accioncs elementales denomindw despkrzcrrniento, reduceion, aceptacih y error {shljt reduce, accept y error respectivamente). Una accion del, mdtlizador sintktico se efKtú;t de l a manera siguiente: 1

1. &windose en su estado vigente, el analizador determina si requiere un token adelantado para decidir que acci6n debe efectuar a continwiún; si requiere dicho token y no cuenta con él, solicita a yylex el siguiente token.

2. Haciendo uso del estado vigente, y del token adelantado en caso necesario, el analizador decide la siguiente accibn y la lleva a cabo; el efecto de la acción ejecutada puede o no usar el token adelantado y meter o sacar estados a pila

Page 39: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Cada estado E del autómata tiene asociado un conjunto de acciones que el analizador sintáctico debe efectuar cada vez que se encuentre en el estado E. &seguida se describen las acciones que pueden estar indicadas en cada estado.

‘La acción de desplazamiento (shift), es la más frecuentemente ejecutada por el analizador sintáctico.

LA accion de reducción evita el crecimiento ilimitado de la pila. Cuando el andi7Aor sintáctico realiza una reduccibn, saca del stack el lado derecho de la produccion y lo reemplaza por el simbolo del lado izquierdo. Puede ser necesario consultar el token adelantado para decidir si se debe, o no, hacer una reducción, pero usualmente este no es el caso.

Las otras dos acciones que realiza el analizador sintáctico son conceptualmente mucho más sencillas. La accibn de aceptacion (accept) indica que la entrada completa ha sido analizada y que cumple con las restricciones impuestas por la gramática; esta acción aparece solamente cuando el token adelantado es la marca--de fin, indicando que el analizador sintáctico ha tenninado su trabajo exitosam&te.

La acción de error por el contrario, indica que el analizador sintáctico no puede continuar el andisis de la entrada, puesto que los tokens leídos. junto con el token adelantado no pueden ser seguidos por nada que resulte m una entrada válida. En este caso, el analizador sintáctico reporta un error e intenta recuperarse del mismo y continuar el análisis.

Cuando YACC es invocado con la opción -v (YACC -v ~archvo>), un archivo denominado y0utput.c es creado con una descripcton lelpble del analizador sintáctico.

Page 40: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

3.6. Ambiqiiedad y conf l ic tos .

Un conjunto de reglas gramaticales es ambiguo si hay alguna cadena de entrada para la cual puede formarse mas de un árbol de parse.

Aún cuando haya contictos desplazamientoheducción u reducciddreduccidn, YACC es capaz de generar un . !,analizador sintáctico. Esto se logra aplicando alguno de los siguientes'' cdtkriospara eliminar la ambigü&:

2. En un conjlicto de reducciddreducción, se decide por la regla que aparece primero en el archívo de especificación de entrada.

El criterio 1 implica que las reducciones son diferidas, siempre que sea posible, en favor de los desplazamientos. El criterio 2 proporciona al usuario una forma burda de controlar el comportamiento del analizador sintáctico fkente al conflicto; los conflictos de reducciddreduccidn deben evitarse siempre que sea posible.

Los conflictos pueden presentarse debido a errores en la entrada, 'errores lógicos o porque las reglas gramaticales, aunque consistentes, requieren un I

andizador sintáctico mas complejo de lo que YACC es capaz de construir. El uso de acciones dentro de las regla. también puede causar conflictos si la acción debe efectuarse antes de que el analizador pueda estar seguro de cual de las reglas se está reconociendb. En estos casos, la aplicacibn de criterios como los anteriores es inadecuada y lleva a la creación de un analizador sintáctico incorrecto. Por esta razhn, YACC reporta el número de confllictos resueltos aplicando los criterios antes mencionados.

Page 41: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Algunas veces, es nwstuio especificar a YAG'(: la precedencia y la asociatividad de operadores en las reglas gramaticales de manera que se pueden evitar conflictos que lleven a un ineficiente aprovechamiento de l a s capacidades de YACC.

Las precedencias y asociatividades son usadas por YACC para resolver codictos en la siguiente formrt:

I. Las precedencia y asociatividades son registradas para todos los tokens y literales que fueron declarados con ellas.

2. A cada regla gramatical se le asigna una precedencia y una asociatividad, que es la del últlmo token o literal del cuerpo de la regla Si se emplea la construccibn %prec, la precedencia explícita invalida la implicita Para algunas reglas gramaticda, la precedencia y la asociatividad pueden no estar definidas.

3. Si se presenta un conflicto dereducci6wkeduccidno de QespZuzaminentcliredttcci6n y ni para el símbolo de entrada ni para la regla gramatical se han establecido precedencia ni asociatividad, entonces se aplican los criterios para elÍrniIlaci6n de ambigitedad descritos antes.

4. Si hay un conflicto de d e s p k r z a m i e n t i 6 n fsh@/reducely tanto para el símbolo de entrada como para. la regla se hart establecido precedencia y wociatividad, el conflicto se resuelve en favor de la acción asociada con la precedencia más alta. Si l a s precedencias son las mismas para l a s acciones de codlicto, se recurre a la asociatividad: la asociatividad por la izquierda implica reduccih, la asociahvidad por la derecha implica desplazamiento y la no sociatividad implica error.

Los conflictos resueltos por medio de precedencias y asociatívidades no son reportados por YACC. Esto significa que el cometer errores en la asignacibn de precedencias y asociatividdes puede disfrazas errores en la gramática; es aconsejable emplear precedencias sdo en 10s casos en que sea imprescindible y emplearlas como "receta de cocina" mientras no se cuente con experiencia suficiente. El archivo y0utput.c es muy- &íI PUR determinar si el cmali;tndor generado hace io que se espera que haga.

Page 42: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

La mmipdacion de errores es un área extremadamente dificil y muchos de los problemas que en ella ,se presentan son de wacter sembtico. Por ejemplo, cuando se encuentra en error puede ser necesario liberar el almacenamiento del kbol de derivwiitn, borrar o modificar entradas de la tabla de símbolos o activar banderas que limiten la producción de una salida incongruente.

Rara vez es aceptable que el proceso de análisis se suspenda totalmente al aparecer el primer error; en general es más uti1 que el proceso continue para detectar todos los errores sintácticos; csto lleva al problema de reinicializar el analizador despuh de un error.

YACC cuenta con un mecanismo sencillo, pero suficientemente general, para brindar al usuario contrul sobre el proceso de recuperación de errores. El nombre error se reserva para la manipulacibn de errores. Este nombre puede ser empleado en las reglas gramdcales y su uso sugiere lugares en los que se esperan errores y donde la recuperación debe llevarse a cabo. Al ocurrir un error, el analizador desapila estados hasta encontrar m o en que el token error sea aceptado. Una vez encontrado éste, el autbmata se comporta c-orno .si el token error fuese el token adelantado y ejecuta irts acciones amciados con el estado encontrado y, después, el token que causo el error se convierte en el token adelantruto. Sí no se indican reglas especiales para manejo de errores? el proceso sesuspende al encontrar e1 primer error.

E l entorno de YACC,

Cuando el usuario proporciona una especificación de entrada a YACC, la salida es un drchvo fuente escrito en C llamado vtab.c.La fuflcibn, producida porYACC se llamayyparse,y es una funcion entera que hace varias llamadas a-yvZex, la fúncicin que efectúa el anidisis lkxico para obtener tokens de la entrada; al detectar un error, -vyparse devuelve d valor I ; si por el contrario se analiza toda la entrada hasta que el analizador Iexico devuelve la marca de-fin , el analizadbr sintktico acepta la entrada y devuelve el valor O.

- -

Page 43: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

El usuario debe proporcionar un cierto entorno para que el analizador sintáctico generado pueda, convertirse en un programa ejecutable. For ejemplo, como en cualquier programa de C , debe definirse una función llamada main la cud llame a yyparse. Por otra parte? es necesario d e h r una firnciún denominada yyerrrr pasa imprimir un mensaje cuando se detecta un emor sintáctico. Estas dos funciones deber ser proporcionadas por

' el usuario.

Una variable global llmada yydebtng de tipo entero, que normalmente tiene el valor O, permite que el analizador sintActico produzca una descripción de 1s acciones (incluyendo los símbolos leídos y ins acciones tornadas) cuando Htdebug toma el valor de 1. El valor de esta variable puede cambiarse EL tiempo de ejecucibn, empleando un depurador.

%(

enm errs { es&%, elexico, eexp, einst, eiddup, eidnodec, efinarch 1; enum contextol { agio, doc 1; mum contexto2 { cdec, cuso 1; enum tipos { tipoentero, tipocmct, t ipohc 1; char * M a ~ . j e s [ l =: { "Sintactico.", 'T,exico.", "Expresion invalida",

"hstruccion invalida", "Identificador ya declarado.", "Identificador desconocido.", "Comentano no cerriido." 1;

enurn errs coderr = esintac; enurn contexto1 alcance = aglo; mum contexto2 contexto = cuso; enum tipos tipoid tipoentero; int offset z: 2; int Itemp = O; ínt Numfoc = O;

#define MAX " SIM 47 yyeKQr0;

Page 44: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro
Page 45: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

%token POR 15 Yotoken ENTRE 16 %token AND 17

Ybtoken NOT 19 %token IGUAL 2.0 %token MAYORIGUAL 21 %token MENORIGUAL 22 Yotoken MENOR 23 %token MAYOR 24 Yotoken L)IE'E&m?'E 25 Yotoken ASlGNACION 26 Yotaken PARENTESIS1 27

Yotoken OR 18

%token PARENTESIS2 28 %token LLAVE1 29 Yotoken LLAVE2 30 Yotoken COMA 31 %token PTOCOMA 32 Yotoken ESCCAD 33 o/otoka ESCNUM 34 %token LEElNUM 35 ohtoken N U N 36 ?ÍÍright '=' OiononwsoC MAYORIGUAL MENORIGUAL DIFERENTE IGUAL MENOR MAYOR %left OR %left AND %left NOT O/oleft MAS MEBOS %left POR ENTRE ?"I MENOSUNARIO %type <cuenta> pars */ótype (cuentx~ listapars %type <cuenta> args

Page 46: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

%S6 prog : deck prin

deck ; deck decl I decl

decl : decvar

3

decfun : FUNCION { contexto = cdec; tipoid = tipofunc; ) IDENTIFICADOR { alcance = doc; ) Iistapars { contexto = cuso; ) cuerpo { alcance = 4 0 ; printf("DECLARAC1ON FUNCTOMn"); Visualiza Tabla(7Iocdes); Anula-Tabla(Tldes); 1

3

decvar : tipo f contexto = cdec; 1 vars { contexto = cusa; ) PTOCOMA

vars : IDENTIFICADOR 1 v m COMA IDbXTIFICADOR 7

tipo : ENTERO { tipoid = tipoentero; printf("TIP0W'); ) 1 CARACTER { tipoid = tipocaract; printf("TIPO\n"); 1

listqars : PARENTESISl PARENESIS2 1 PARENTESIS1 pars PARENTESIS2

7

par : tipo IDENTIFICADOR. ;

Page 47: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

cuerpo : LLAVE1 ínsts LLAVE2 1 LLAVE1 LLAVE2 Y

ins& : inst .. 1 insts inst

9

: TDmFICADOR ASIGNACION expr PTOCOMA DEVUELVE expr PTOCOMA decvar [DENTIFICADCIR PARISTESISI args PARENTESTS2 PTOCOMA

SI PA!4.RENTESISl expr PAREN'IBSIS:! inst SI PARENTESISI expr PMNTESIS2 inst OTRO inst MIENTRAS PARENTESIS1 expr PARENTESIS2 inst LLAVE1 inst LLAVE2 ESCCAD CADENACARACT PTOCOMA ESCNUM expr PTOCOMA

NLIN P'rOCOMA error PTOCOMA

[DENI'IE'ICADOR PARENTESIS 1 pmmsrs2 PTOCOMA

1 IdEENUM IDENTTFICADOR PTOCOMA

1 expr args COMA expr

: lDENLlFICADUR CADENACARACT

CTEZNIERfl PARENTESIS 1 expr PARENTESIS2 IDENnmCADOR P,4REiNTESISX tugs PARENTESIS2 IDENTIFICADOR PARENTE23ISl PARENTESIS2 expr AND expr expr OR expr expr ME3IONGUAL expr expr MAYORIGUAL expr expr DIFERENTE expr expr IGUL4L expr expr MENOR cxpr

c - n x m c r

Page 48: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

expr MAYOR expr MENOS expr %prec MENOSUNARTO expr MAS expr expr MENOS expr eipr POR expr expr ENTRE expr

I NOT expr error PTWOMA { yyerrok; coderr = eexp; yyerror();

: PRINCIPAL, PARENTESISI PARENTESIS2 cuerpo

Page 49: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

El ejemplo anterior es una especificación de entrada para l'i4CC en la cud se incluye una gramática que es parte de un subconjunto del lenguaje de programacih PnscuE y que el programa que genera YAC'C es una analizador sintktico para esta grarnática.

Page 50: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro
Page 51: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

P A R T E

D O S

Page 52: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

P R O G R A M A C I O N

C O N C U R R E N T E

L E N G U A J E S

C O N C U R R E N T E S

Page 53: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

A . P R O G R A M A C I O N

C O N C U R R E N T E

Page 54: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

1 m INlRODUCCl6Nm

Ea un proyecto, como la comtmxión de un sidema, el trabajo generaImentc M divide en *as en& a entidades que trabrqan con ciexbmdepenhcia sin embargo, para reaIizBlf debidamente el proyecto es necesario sinamizar las actividades que se desarrollen simultheamente.

Usamos el término coIu;ru7B1Icia para denotar elparalelismopotencial presente en las actividades de un sistema A las ddades activas les ll~luemosprocssos.

1 De este ejemplo haremos dos observaciones i m p o r t a n t e s . Primero, tenemos que : r e c o n o c e r que siempre se pueden mmrporar mhs trabajadores al proyecto. No obstmte, el proyecto no estabíece esto como unaneccaidad sino como una comidemcibn para mejorar surendimiento global. Sm embargo, se ha observado que despds de cierto número de trabajadores, ell rendhato d e l sistema no crece proporcionalmente. Por otra parte, la segunda observaciún se refiere a mejorar la esbwtum de la orgamIzaci6n drahngmardo, separando y codinando el trabajo d.izado, lo que si@= una mayor especializacich tanto ea las actividades como de los *adores. LOS &temas que involwmn mncurrd son de gran importancia te&ica

y práctica, debido a la elevada capacidad de &&acción que se alcanza al modelary simular el comportmiento de problemas des.

Las caracteristícas de este tipo de problemas son:

a El ambiente ests formado por nummprucesos que actúan al mismo tiempo a dif" velocidades.

b. El orden en el que ocurren l o s procesos es impredecible. Por esta razón, IosprograFnas c-S SORm d e t e n n a s t i c o s .

c. Los p?"sos concurrertes pueden funcionar con total mdvdenc ia unos de otros, o pueda ser asindnicos.

d. Las velocidades relativas de losprocesos no son sigruficativas.

Page 55: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

2 cARAcTER(sTIcAs ME LOS LENGUAJES COMCURREWTES

2.1 Modularizacidn.

a Procesos.

El proceso es una pieza fimdameatd en ed didio de un programa concurrente. Rocesos asincrorws que tima que comunicarse y

Un proceso, al igual qm unproqmm, posee m flujo de collfrof propio que qealta ilwtMxioncs o procadindartos ~ c i a l m a l t c . Los prtxesos son entidadSS activas que corren asíncronamente.

Page 56: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

En un caso fsiMB1, los procesos pueden compartir todas las variables.

progmmdores timen que cmstmir rms propios esquemas de sineb. En e4 caso m& I"egfTicfivo, los procesos no comparten ninguna variable. La comunicaci¿m y Ia sincmnimcih p u e d e n ~ r r o l ~ m c d i ~ una utilidad para pasar measaja, o bien por paso de parámetros entre procadirrrientosindepcndi~.

En este cam, pars prevenir errores depcndim del tiempo, los

El compiledor puede aseigurar, al compilru, que no se produzca wmpartiuh, de aquí queno se prod- errores dcp..cndterrtc;sl del tiempo ocasionados por variables cornpertidas.

Así, un proceso consta de unos datos locales, y un programa secuencial que puede operar sobre los datos . Los datos locales dilo sefsn accesiblesdesdc: el programa secuencirrl, mtxapsulado dcutro delmismo pruceso. 0 st8, un proceso no puede acceder diredamate a l o s datos locales de otro proceso. Si los procesos pueden compartir datos globales, estos tiesen que deíinirse en un Brea comb 6 encapsularse en un procedimiento di tip abstracto de &tos.

b. Procedimientos.

Elpmcedhinto es la unidad básica para el ocul~mto de l o s d d e s de la implcmartacibn de un m&odo de acceso a los datos. La implcmcntacih, consiste del canjunto de operaciones que se aplican en forma secuenciai sobre l o s datos. Este conjunto queda oculto bajo el nombre del prmdirnhnto. Un promlimiento es una entidid p i w porque se maniíiesta cuando recibe el control de la ejecución durante su llamada

Un prm&miento (subrutiraa) cs otra unidad de mdkiurizacidn que encontramos em cdquier lenguaje de alto nivel. Si un procedimiart0 puede incluir sus propias variables permten- (variables que no desagsrecca entre lkunadas a procedimiento), entonces dentro de un procedtmiento

eincapsulsrse algmos datos globales Un proceso no puede acceder a estos dabs dimctamcnte, para ello tenM que invocar el procedimiento. Iistt CncapSuIBao resguarda a los usuarios del promdiminto de l o s detalles de su implementacib~ pemitihdoles con- en como 4 implementado realmente.

Page 57: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

c.Clases (Tipos Abstractos de Datos)

Un proadimi- nos ofiece M mecanismo Mtado para la ocultaci&n de idormacih. Para ocultar cmnplehmente el m W o de de.€iniuhdedatnstenumsquerccuniraunconjunto de mecanismosmbs complicado. Necesitamos una utilidad que pennita al programador crear una clase de objetos sbsbractos que no .byan sido explícitamente definidos en el diseflo del lenguaje de progtamcibn. Se conoce corrientemente curno T i p Abstracto de &tos.Un tip abstracto de &los se caracteriza por un amjunto de operadores ddinidos por el progranador. Se represeatan mediante ladtclsrsci6n devariables cuyos valores defíncn el estado de una instancria del, tipo, asf como los cuerpos de los procedimientos 6 fiwclones que implementan las operaciones sobre el tipo.

Así, una C h e es un mecanismo que permite emcapsular variables y procadimientos de d o a las propiedades que exhiben los datos. Los mecanismos para la deckacih de las clases quieren cierta flexibilidad para crear nuevos tipos de datos que el lenguaje no provee pero el programador puede llegar a fomdar.

Denominamos Clase a un mddulo de program que o h la repmmxtacih de un tipo abstracto. Este ttrmino fue introducido en el simulp67 pahl y cob. 19681 y se utiliza em el lenguaje Comwrmt Pascal mrinch Hiansen, 19751. La sintaxis de una clase es:

decllvaciones de variable type Class-name = class

procedure P1 (...); berP ...

Page 58: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Obviame, la repretmtación de un tip abstracto ds datos no debería ser utilizahs dhxtamente por componentes del programa que no fbmm sus operadores; en caso contrario, la consisteacia de la abstracción podría resuhar comprometida Esta dccih es el requerimiento básico impuesto a un lenguaje que soporte abstmaiones defuidas por el programador. Ad, unproce&ignto definido deatro de una class 610 puede acceder a las variables declaradas locdnmte dentro de la ckse y a los pariimetrrrs formales. De ig u a l forma, l a s variables locales de una clase ímicamente pueden ser accedidas por losprocedmimtos locaks.

El mecanismo por el que una implementacíón de lenguaje impone una protezción estática a los tipos dedinidos por mddulos se basa en una reformulación de las re@s tradicionales de los lmg@es estmdmdos en bloques.

2.2. Administracidn de procesos.

Durante su e x i ~ c i a , un proceso pasa por una serie de estados dkretos. Varias circmcias pueden hacer que un proceso cambie de estado.

Se dice que unppoceso st dejemtando ( es decir, d en estado de ejtcucih), si tiene cn ese motmarfo la UCP. Un proceso se dice que est& listo (es decir, en estado de listo), cuando podría usar una UCP, si hubiera una disponible.. Se dice que un proceso est4 blbqueado (es decir, en estado bloqueado), si espera que ocurra algo (como la termimitin de una entradalsalida) para poder ponerse enmarcha

S610 se puede estar corriendo un proceso al mismo tiempo, pero puede haber variosprocesos listos y varios nuis bloqueados. Por tanto, establecemos una lista de listos para l o s procesos listos, y una lista de bloqueados, para l o s bloqueados. La lista de listos se mantiene en orden prioritario, para que el siguiente proceso que reciba la UCP sea el primer proceso de la lista. La lista de bloqueados d desordenada -los procesos no se desblquem ( o sea, no quedan listos) en orden prioritario; ea l u g a r de esto, los procesos se desbloqueen en el ordm en que timen l u g a r l o s evcntos que e&n esperando.

Page 59: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Los proceso.^, como entidades de un programa, se pueden espdflcar, &elarar, craw o hstmir.

a . Especificacidn de procesos. El lenguaje debe ohcer un declarador que permita d d b i r la estructura y d compo*& delos procesos.

c. Creacidn de procesos . Los procesos concurrentes pueden ser esstfticos, cuando se crean al principio de la ejecuci6n del programa mediante la dbclaracidin, 6 dinbnicos, cuando se crean durante su ejccuci6n.

d. Terminacidn d e procesos. Este punto eg muy importante tanto para la veriíicacih de programas como para el fimcianendeato correcto del admmstd or de procesorp. Por sencillez, se puede decir que M proctso temina cuando el control alcanza el finel del bloque que d&e su comportamiento. Por ejemplo, surgen v&os problemas cuandounprocesoAcreaaotroprocesoByAtemÍnaantesqueterrrkineB.

. .

2.3. Sincronizacidn entre procesos.

La btemccih entre procesos es el aspecto central de la programcidn concurrente. De nada sirve que existan varios procesos si éstos no se coofdhfan para trabajar m o p d v a m ~ . €31 el esquema de toplogia esttftica entre procesos, los enlaces de smcronhci6n 6 cornunicacih no cambian en el programa Ijtl la topbgia dnhica, los enlaces pueden establecerse durante la cjecUci¿jn, creando 6destruyendoenIacesentre procesos.

Los daas de sincxmhción alparecen cuando los procesos accesan ciertos mecatlismos impleznerttados como objetos ( por qemplo, l o s semhforos) o como estnrcturas de confroi (por ejemplo, las regiones mfticas C O P K # ~ ~ O M ~ S ) .

Page 60: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

La faltade ellos puede dar l u g a r a errores dependientes del tiempo cuando l o s procesos ejecutan el mismo fhgmnto del texto de un programa y/o modifican a las mismas variables.

Un problema fiardarneatal en la programucídn concurrente es d de la twdltrsidn m t w , que se presenta cuando dZerentes procesos compiten por recursos comunes como, por ejemplo, el procesacdor, la msmoria, los canalas ds comunicacidn o los dispsitivvs externos. Q C O ~ C ~ P ~ O de exclusidn mum se refiere: a una región de datos o de instrucciones, llamada regidn criticu, que nunca debe accedeclse por más de un proceso al mismo tiempo.

Para evitar el problema de la exclusih mutua, haremos las siguientes S-ciones respecto alas regiones críticas:

1. C u d 0 unprocsso intenta eartrar a ~118 regidn rrli.ica, IO C O X U @ ~

después de cierto tiempo (finito e indeterminado).

2. A lo más unprocsso a la vez puede encontrame em la regidn criticu.

3. Elproceso permanecerá en la rolgi6n crítica por un tiempo limitado. El primer punto asegura que todoproceso que desee entrar a la regidn

crfhica eventualmente lo comeguirá El segundo establece la condición invariante de la exclusi3n rnuhra. El tercero afirma que la actividad de M proceso ea la regidn crftica debe termina. El primer y -do puntos imponen restricúona a la ahinistradn ds losproasos:

a Cuando no hay un proceso en la regidn crítim, cualquierproceso qwdeseeemtmrenestapuedehacerioinmediatamente.

b. Cuando un proceso se encuentra en la regidn crítica y otro intenta entrar entonces, ésteúltimo pospondrásuentrada

c. Cuando un proceso abandona la regidn crftica mientras q w otros íntemtar~entrar, solame!nteunodelosprocesosque tmtm de entrar será cepazdehacerio. La eleccih puede ser arbitraIía o puede hacerse siguíeado alguna política que evite otascurnientos, como la de la cok: el primero en kgar es el primero en entrar. EI atascamiento se presenta cuando un proceso pospone su i npa0 indefinidamente.

Page 61: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

d. Las actividades anteriores se realizan en M tiempo limitado e in-.

Recspitulando, la excZusibn mutua necesita ser aplicada sólo cuando un proceso acceda a datos compartidos; cuando los procesos ejecutan operaciones que no estén en CoIlflictO entre sí, debepemiirseles proceder de forma conamente. Cuando un proceso está accediendo a datos comgartidos se dice que el proceso se encuentra ea su seccibn crítica (o reg$& crítica). Cuando M pruceso esté en su secddn crítica, todos los demás procesos S& excluidos de sus propias secciones &cas.

Mientras M proceso se encuentre en su sección crítica, los demás procesos pueden confinuar su ejecución f'bm de sus secciones críticas. 4

Cuando M proceso abandona su sección crítica, entonces debe permitirsele proceder o otro proceso que espera entra en su propia sección crítica (si hubiera un proceso en espera).

Ektm dentro de una seccibn &ca es un estado muy especial asignado a un proceso. El proceso tiene acceso exclusivo a l o s datos compartidos, y todos los d d procesos que necesitan der a esos dstos permmecen en espera Por tanto, las secciones &cas d e h ser ejecutadas Io más rápido posible, M programa no debe bloquearse dentro de su secci&n críticu, y las secciones críticas deben ser CodifiCBdas con todo cuidado (para evitar, por ejemplo, la posibilidad de in& en ciclos inJinitos).

Si un proceso dentro de una seccidn crfiica termina, entonoes, al realizar su lunpieza de terminación, se debe liberar la excZusi&n mutua para que otros procesos puedan eatrar ea sus secciones criticas,

Para manejar la excZuilln mutua, el lenguaje debe ofrecer ciertos mecanismos de sinmmizacih y acceso exclusivo que obliguen a l o s procesos a coordinar sus acciones.

Page 62: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

2.3b1. Primit ivas de exclusi6n mutua.

Las cumtnmiones implantadas para entrar y salir de la g;reclusidn m u m en un algoritmo para un proceso., encapsulan el &go en cada proceso que accede a la variable compartida por los procesos, es decir, estas constnuxiones delinean las secciones críticas. Estas operaciones se Ilaman, aveces,primitivvrs ds exclusidn mutau; o sea, que mvocan las operaciones más fimdamentdes inherentes a lac~xclusión mutua.

Ean el c8so de: los dos proce9;os, estas primitivas operan como sigue: cuando procesomo ejecuta ~ciusionmutua, si procesodos no está en su sección crítica, d e a la variable deseada y después ejecuta s a l e d e a ~ c l u s í o m ~ para indicar que ha abandonado su secciiln crítica

Si procedas está en su seccih crítica cuando procesouno ejecuta ~clusio~utua,entoncesprocesounoentm en estado de esperahasta

p d e r a entrar en su seocijln critica, que procesodos ejecute s8ledeexclusi~m~ Procesouno p d , eatmces,

Si procesouno y procesodos ejecutan entraexclhmutua simultáneamenk, entonces le será permitido proceder a uno, pammeciendo el otro en espera Ladeccibn es hechaal azar.

2.3-1.1 Implementacidn de las primitivas de excl usicin mutua .

Se busca una implementación de entraexclusionmutua código de entrada a exclusión m- y saledeexclusionmutua &digo de salida de exclusión m- que satdkga las cuatro resfricciones siguientes:

Page 63: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

b. No deberá. hacerse ninguna suposición en relación con las velociddes retativas de pvwesos concur7entes asincrdnicos.

c. Los prmsos que se emuentm operando fuera de sus secciones críticas no pueden evitar que entren otros procesos en sus propias secciones crítim

d. No debe pcxtergme indefinidamente la entrada de 10s procesos en sus secciones crÍticas.

Una implemdón elegante de software de la exdm3n mutua fk la pmentada por priment vez por el dco holm& Dekker.

2 3.1 12 Algoritmo de Dekker.

La siguiente figura muestra un primer intento de espacificar el &digo para fonar la qhcacibn de la excZusi&n mutua, dentro de1 confexfo de un programa concurrente con dos procesos.

Page 64: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

dondeparbsginparSnd indican que la ejecución semeacial de procesouno y procesodos debe ser dividída entre varias seswncias de ej&¿jn en

procesodos operen como procesos concurrentes. Cada uno de &os procesos entra ear un ciclo indefinido, entrando y reentrando repetidamente en su sección crítica. Aquí ea&adcusionrn~ se hplemeata por un údo mientras simple:, que mantiene el ciclo hrtsta que procesouna iguala al número del proceso; saledeexclusionmutua se implementa por una hstmcciicin simple que ajusta procesonumen, al niunen, del otro proceso.

paralelo. (trayectorias de coaffof). Esto es, indican que procesouno y

Procesouno ejecuta el while do. Como procesonumeao es inicidmmte uno, procesouno entra en su seccih crítica Procesodos en- procesonumero rgual auno y permanece en el ciclo while do. Cuando procesodos obtiene el procesador, simplemente permanece en el ciclo en espera de que procesonumero se ajuste a 2, así que procesodos no entra en su sección crítica y la exclusib mutua queda garantizada

Procesouno acaba par temrinar fa ejecución dentro de su seccibn &ti@ de suponerse que no hay ciclos infinitos) y ajusta procesonumero a 2, permrtiendo asi que procesodos entre en su sección critica,

LaexcZusibn mutua está garantizada pero el precio es alto. Procesouno debe de entrar primero, así es que si procesodos d listo para eatrar en su sección critica, deberá tardar bastante. Despds de que procesouno entre y salga de su setxi& critica, entonces presodos &beniseguir, aun cuando prwxmuno desee reartnu procesodos no esbi listo.

Page 65: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

I3n laprimenr s o l u c i ó n d a sokmde una variable global simple, y esto forzeba la aparición del problema de sindh bloqueada Así es que, en la vemih dos siguiente, se usan dos variables: prlderrtro, la cual es venidera si procesouno edá dentro de su seccirin crítica, y pr2dentr0, que es verdadera si p d o s ddentro de su sección crítica

while prldentm do pr2daltro := me; doncritídos; pr2deatro := false; otrascosasdos;

Page 66: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

A h o r a , m i ~ pr2detrtro sea verdad- procesorrno pennenece encerradoenuna espera, Procesodorr acaba abandonando se sección crítícay realizasu propio &go de dda de exclusión mutua., ajustando pr2dCntro em falso. Procesouno ajusta entonces prldentro en verdaden, y entra en su sección crítica Micntras prldentm seaverdadera, procesod<w nopodrsentrarensuseccibncrítica

Las sutilezas de la programacidn concurrente vuelven 8 salir 8 la superficie. Como quiera que procesouno y procesodos son procesos cuncurrentes, ambos podrían m-tar de forma simulthea sus sememias de &digo de entrada exclusión mutua En principio, tanto prldentso como pr2dentro son falsas. Procesouno podría probar prZdemtm y umntmrla entonces, mtes de que procesouno pueda dejar ajustar prlddro em vcrdadem, procesodos podria probarprldentro y encontrada Wsa En este punto, prcscesouno co1ocaprlde;nbro en V ~ ~ o y ~ a s u ~ ó n c r i t i c a A m b o s p r o c c s o s s e e n ~ e s l s u s secciones críticas al mismo tiempo, así es que la versión dos ni siquiera g m m t b la aazZusi&n mutua

EnIaversi6ndoscxistcunadificdtad,puesentreel tiempo enqueun proceso dekmitm(emprueba de mi-) que puede seguir adelante y el t i ~ ~ q u e e l p r o c c s o q u s t a ~ b a n d e r s p e r a i n d i c a r q u e ~ e n s u

berndera y enbx en su secci6n crítica Por tanto, una vez que el proceso intenta la prueba de mieatras, debe tener la seguridad de que el otro proceso no pueda ir mh 8119 de su propia pIueba de mientras.

sección &tic& hay tiempo suficiente para que el otro proceso pruebe su

Page 67: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

La versibn tres siguiente, intenta resolver esto haciendo que cada proceso ajuste subanderaantes de la ejecucih del m i e n t r a s .

program versiontres; var prIquiementrar, pr2quiereea2trar : boolean;

procedure procesouno; begin whiletruedo

prl quicrteatsar := true; while prZquirclentrar do seccioncriticauno; prl. quiereentrar := false; otrascosamnlo; end;

=k procedure procesodos; - while true do b W pr2quiaeentmr := true; while prlquieremtm do seccioncriticados; pr2quiereentm := false; otrascosasdos; end; en&

begin prl quiereentrar := false; pr2quiereentrar := fialse; P d @ procesouno; procesodos;

p-d; end.

Page 68: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Se ha solucíodo un problem& pero se ha creado otro. Si cada proceso ajusta su bandera antes de proceder con la prueba de mientras,

entonces, cada proceso se enamtmrá am la bandera del otro ajustada y entrarh para siempre en el ciclo hágase m i e n t r a s . Este es un ejemplo de un interbkrqwo de dos procesos.

El problema de la vmión tres es que todos los procesos pueden eammrse en su ciclo hágase mientras respectivo. Eis necesaria unamanera de "romper" estos ciclos. La versión cuatro l o p esto al forzar cada proceso de ciclo a ajustar su bandera en fiho repetidamente en períodos breves; esto permkid al otro proceso p d e r más all8 de su prueba de mientras, con su bandera t0da.a conectwk

Page 69: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

przquíer-:”; delq(random, algunosegundos); pr2quiereentrar := true;

end; doncriticados; pr2quiereemtm := false, 0kWOSfdOS;

en4 end;

prlquiereentrar := false; begitl

pr2quireartrar := false, Parbegtn procesouno; procesodos;

p-4 end.

La exclusidn mutua queda garantizada y no pue& ocurrir el intsrbloquso, pero puede pmenbme otro problema devastador en potencia, el de pshwgacidn indkjinida. Veamos como. Debido a que no pueden hacerse suposiciones acerca de las velocidades relativas de los promsm concurrentes ashmonos, habrá que considerar todas las secuencias de ejecución posibles.

El proceso podría, por ejemplo, proceda en &dm. Cada proceso puede seguir la secuencia siguiente: ajustar su bandera em verdadero, hacer la prueba de mímtras, entrar en el cuerpo del ciclo mientras, ajustar su bandera en falso, ajustar su bandera en verdadero y, luego, repetir la secuencia, comenzando con la prueba de mieatras. En tanto hacen esto, las condiciones de prueba perman& ver-. Desde luego que la probabilidad de que tal o p d ó n ocurraes muy baja, pero puede o c u r r i r . Por tanto, la versión cuatro es inaceptable. Si un sistema que utiliza este tipo de exciusih mutua estuviem controlando un vuelo espacial, un m8fc8pEIsog cardí8co o un sistema de control de tráfico akm, la posibilidad de que ocurra una postergación indefmida con el conseczlente fallo del sistema se dispararía.

Page 70: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Ensblounascusplteslíneas de &digo, el a2gon'ho de Debmanejade maneraelegante la exclusión mutua de dos procesos sin necesidad de ningunainstnmihespecialdehardware.

program algorittmod~er; var procesofavorecido : ( primero, segundo); prlquiemmtrar, pr2quiereentrar : b o o l e a n ;

p d w pIncesOun0; begrn whiletruedo

begin prlquiereentrar := true; while pr2quieretmtrar do ifprocesofavorecido O segundo then

prlquiereentrar := false, while procesofavorecido = segundo do

prlquiereentrar := true;

seocion~cauRo; procesofavorecido := segundo; prlquieredmr := *, o ~ s a s u n o ;

end; end;

begin whileduedo

procedurtproccsodos;

btgin pr2quimtrar := true; while prlquiexeentrar do ifprocesofavorecido = primero then begrtn pr2quiereeatrar := false; wfnile pmcesofhvorecido = primero do pr2qui- := true;

end; seccioncriticados;

Page 71: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

procesofsvorecido := primero; plZqlabxeektl-ar:=f$se; otrascosasdos; -4

en4 ”

pr1quiereent.m := false; pr2quiaceartrtlr := fib; procesofSvorecido := primero; Parbegm procesouno; procesodos; parend;

end.

El algoritmo de h h resuelve la posibilidad de la postsrgacidn indetnih mentada en la versión c u a t r o . Veamos cbmo. Proceso uno indica su desea de entrar en su sección critica, al conectar m bandera (ajustarlaen v-). Fdaonces procede con la prueba de mientras donde verifícasi procesodostambién quiere entrar. Si labmdera de procesodos está desconectada (ajustada en fBfso), entonces procesouno dta el cuerpo d e l ciclo mi- y entra en su sección crítica

Supóngase, sin embargo, que cuando procesouno dce la prueba de mientras, d d r e que la bandera de procesodos está conectada Esto obliga a proceso~o a. entrar al cuerpo del ciclo mie&as. Aquí busca la variable

c d o ambos procesos desean mtrm al mismo tiempo em sus secciones críticas. Si proce%ouno es el favorecido, salta el cuerpo del if y ejecuta repetidmente la prueba de mientras, esperando a que procesodos desconecte su bandera. (Pronto veremos que proasodos debe acabar haciendo eso).

procesofavorecido, que se U t h a para resolver losconflictogquesurgen

Si proceso uno detemina que el proceso fkvorecido es procesodos, entonces procesouno e6 forzado a entrar en el cuerpo de if, donde desconecta su propia bandera, entra al cid0 del prirximo mientras y pemnmecc allí en tauto p r d o s siga sieado el proceso favorecido.

Page 72: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Al desconectar su propia bandera, procesouno permite a procesodos entrar en su seccih crítica Procesodos acabara abandonando su seccibn crítica y ejecuEeris su &go de dida de exclusión mutua Estas proposiciones ajustan el proceso favorecido de vuelta a procesouno y desconectan la bandera de p d w . Procesouno puede eatnu ahora al mientras interno y conectar su propia bandera. Procesouno realiza ahora el mientras extemo. Si la bandera de procesodos ( que acaba de hnectarse)sigue a h descanectada, eatonces procesouno entra en su Seccibn crítica Sin embargo, si procesodos intent6 reentrar nipidameate en su seccibn crítica, entonces 1 a b a n k de procesados estad conectada y procesouno sefii obIigado de nuevo a entrar ea el cuerpo del mientras externo.

En esta ocas&, sin embargo, procesouno esth '''Sentado en el asiento del conductor, debido a que ahora es el proceso favorecido (rec- que cuando procesodos abandon6 su e611 crítica, ajd procesoffavonxido al primero). Asi es que procesouno salta el cuerpo del if y qecurta de fonna repetida la prueba de mientras externo, hasta que procesodos, "h&dementeWy desconecte su bandera pezmitiendo eartrar en su seccih crítica

Considere la siguieate posibilidad itrteresante. AI salir procesouno del ciclo interno de espera, es posible que pierda al procesador, y que procesodoscomp~eteelcido e intente entrar denuevo en suseccih crítica Procesodos coltecctvB entonces su bandera primem y entrar& en su seccih crítica. Cuando procesouno obtenga de nuevo el procesadoor, con- su bandera Como será el turno de procesouno, si procesodos intenta entrar, desconectad su propia bandera y Sers obligado a ~R&ZU al cido interno de espera, y procesouno podráentrar en su seccibn crítica De esta mera este truco no dará como resultado u118 psterguddn indsfinidrr.

Page 73: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

2 . 3 . 1 . 3 - Exclusidn mutua de n-procesos.

Lhjkstra fúe el primero en presentar una solución de software para la implementación de primitivas de exclm'dn mutua de n-procesos. Knurh respondió con una solución que eliminaba la posibilidad depostergucidn indsfinidn del algoritmo de LXjhtra, pero que aim permitía que un proceso experimentara un retraso (en potencia) largo.

Esto ped una serie de intentos por encontrar algoritmos que acortaran l o s retmsos. Eknbwg y MiGuire presentam una solución que garantizaba la entrada de un proceso en su sección crítica en n-1 intentos. Lampr t desan-olIó una solución que es particdarmente aplicable a l o s sistemas de proammiento distribuido. El dgoritmo usa un sistema de "toma de boleta", como el usado en las pauaderías muy concurxi@ y ha sido apodado e l . algoritmo de la panadería & Lumprt. Brinch Hamen analiza también el control de la conaurm'a entre procesos distribuidos.

2.3.2. Semdf oros . Bjhtra extract6 las nociones clave de la exclusidn mutua en su concepto

de smdforo. Un semiforo es una variable protegida cuyo valor puede ser d d o y alte1.ad0 tan sólo por las operaciones P y Y y una operación de Ínici*ón que U s m a r e m o s inicialimcidn ds semiforo (semaphoreinitialize). Los semiforos binarios sólo pueden tomar los vaiores O y 1. LAB semíforos contadores pueden tomar valores enteros no negativos.

La operacidn P en el sem&foro S, escrito PP), opera de la manefa

siguiente:

Page 74: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

LA opracidn: Y en el sedforo S , escrito V(S). opera de la manera siguiente:

lqun00:mhsprw;esos~esesperaens) then (deja proseguir a uno de estos procesos)

e l s e S : = S + l ;

Supondremcs que hay una disciplina de colas del primero-en- entrar-primemen-salir paralos procesos que esperan a completar M P(S).

Los valores de Py Vson mdivisibles. La edus idn mutua ea ed s d f o r o , S, es aplicada en P(S) y Y@). Si varios procesos intentan ejemtar P(S) al mismo ti-, S610 uno podrá proseguir, los olros permeneecerán en

Los semtiforos y las operaCones de sd foros pueden implemglcarse en software o hardware. Son necesarios para controlar los cambios de escado de unproceso.

I3 siguiente dgoritmo rnuedra cómo pueden &izarse los semtWoros para aplicar la exc2uidn mutuu . Aquí, P(aCtiv0) equivale a entraexclllriónm~ y V(actiw) equivale a saledeexclusionmutua

Pro- e j e m p 1 0 ~ 0 1 0 u n 0 ;

procedure procesouno; var activo : semaphore;

while true do begrn

cosaspreliminaresuno; P(activ0); Seccioncriticaunct;

obrascos8suno; V(activ0);

end; aid;

Page 75: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

procedure procesodos; begin

whiletruedo

besrn COSaspreliminaresdos; P(activ0); Seccioncriticados; V(activ0); o t r m d s ;

end; end;

begin semaphoreinitidue(activo, 1); Parbegm

procesouno; procesodos;

glare!l& end.

2.3.2.1. Sincronizacidn d e procesos con semáforos.

Cuando M proceso emite una peticíón de errtrada/salida, se bloques a sí mismo para esperar a que tennine esta operación. Algunos procesos deben despeatar al proceso bloqueado. Tal interacción es un ejemplo de un protocolo bloqueo/despertar.

En forma más general, sup- que M proceso desee ser in5ormado de la ocurrencia de: un evento. Supóngase que otro proceso es capaz de detectar que ese acuntecimiento ya ha ocurrido. a siguiente dpritrno muestra d m 0 pueden utilizarse las operaciones de semiforos para implemenbx un mecanismo simple de sincmnhción de blbqueo/&spribr de dos procesos.

Page 76: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

begin semaphor~~eventodeinteres, O); P h * pl-aeesouno; p r d o s ;

parend;; end

Procesouno ejecutsdgunas cosaspreliminarcs y despds ejecuta P(event0deinter-k). EI sem&foro ha sido i n i c i w o a cero, de modo que el proceso debe qm. El procesodos ejecuta V(eventodeinkrés) para seiralar que el evento ha ocurrido. Esto permite p d e r aprocesouno.

Obsérvese que este mecanismo trabaja incluso cuando procesodos detecta y st5ala el evento antes de que procesouno ejecute P ( e v d e i n t d s ) ; el sediforo habd sido m c r e m d o de O a I, así es que P(eveatodeinterb), simplemeate ha decrementado el semhforo de I a O, y procesouno pmseguid sin tener que esperar a que ocurra el evento.

Page 77: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

2.3.2.2, La re lac i6 .n Productor-Consumidor.

€31 un programa seaencid, cuando un procedimiento llama a otro y le transmite datos, l o s procedimientos son parte de un proceso simple y no operan de forma concurrente. Pero cuando un proceso transmite datos a otroy l o s problemas son mucho m& complejos. Tal transmisih es un ejemplo de commicaci&n intetprocesos.

Considkse la siguiente relacih productor-cortsmkibr. Suphngase un proceso, unprotktor estlzcperando S o d h n que utiliza M segundo proceso, M cornmidor. Supóngase que se comunican por medio de una variable compartida entera sencilla, bufknutnero. El productor realiza aIgmos d c d a a y despuh escribe el resultado en buffernwnero, el ccmsumidor lee los datos de buf€íérnumem y l o s imprime.

Es posible que los procesos productor y commi&r trabajen bien en &dm, o que sus velocidades de ejec;Ucih sean muy dispares. Si cada vez que el productor deposita un re~dtad~ en bufbrnumero, el consumidor lo leey b imprime de inmediato, entonces la didaimpresa representa& fielmente la coniente de nl'uneros geac=rada para elproductor.

Pero suphpse que las velocidades de los procesos son dispares. Si el cormmidor d operando con m& rapidez que el productor, el consumidor puede leer e imprimir el mismo nirm.em dos veces ( o muchas veces msS ) antes de que el productor deposite el n b e m siguiente. Si el p r d c t o r estci operando rnk r4pido que el consumialor, el prociuctor podría re escribir el resuItado previo antes de que el amsumidor tenga la oporhnilidad de leerio e imprimdo; unprcxhctor muy veloz podria hacer esto muchas veces, con lo cual muchos resultados se perderían.

Como es evidente, el comportmuento que deseamos aquí es que e1 paductor y el commi&r operen de forma tai que los datos escfifos en buffemumero 110 se dupliquen ni se pierdan La aplicacihn de tal comportamiento se conoce como simonizacith de procesos.

Page 78: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Program relacionproductorconsumidor; var accewexclusivo : semaphore;

numerodepositado : semahore; buflkmumero : mtegm,

procedure procesoproductor; var sigUi"0 : i n t e g e r ; begin while true do

begin calcuiaelsiguienteresultado;

buff"numer0 := siguienteresultado; V(accleS0exclusivo); V(nmer0depositado);

P ( ~ e x c l u s i v 0 ) ;

end; end;

var siguienteresultado : Integer;

while t rwe do

procedure procesmmskdor,

begin

begin P(numtr0depositado);

siguienteresulado := bufknumem;

write(siguienteredtado);

P(accesoexclusivo);

v(accesoexc1usiv0);

card; end;

Page 79: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

begrn semaphoreíniti~lrze(accesoexclusivo, 1);

semaphoKeiniti~numerodepositado, O); P- procesoproductor; procesoconsumidor, p==i;

end.

Aquí hemos iltilizado dos s&foros: au;esoexclusivo se utiliza para aplicar el acceso de eazltcsidn mutua a la variable compartida, y numer0depos.í~ se usa para la siwonimcibn dslproeeso.

2*3*2.3. S e d f o r o s Contadores,

Estetipo de ,semiforos son particularmente Útiles cuando unrecurso va a ser asignado desde una bolsa de recursos idekticos. El s d f m o se inicializa para (:I númexo de recursos de la bolsa Cada operacidn P decremeata e3 semiforo en 1, indicando que se ha extrafdo otro recurso de la bobay d siendo usado por M pmceso. Cada oprucidn Yincremetrta el semiforo ea 1 , indicando que un proceso ha devueito un r e c m a la bolsa, y puede ser asignado a otro proceso. Si se intenta una oprucidn P cuando el sedforo ha sido demematado hasta cero, el proceso debe esperar hasta que se devuelva algún fiecurso a la bolsa por medio de una opracibn Y:

2.3.24. I m p l e m e n t a c i c j n d e Sema’fczros, P y V.

Dado el ulgt?rit?no de D&er y/o la dqonibilidad de una insauccl on da hardware testan- la implementacibn de P y Y en espera de ocupado es fricil. Pero la espera de ocupado puede ser M despilfárro. Se ha observado que un proceso que hiciera la petición de una operacibn de ent.rada/salida se bloqueaba voluntariamente, pendiente de la terminacicin de esta 0perraci6~. El pr;oceso bloqueado no está en espera de ocupado. En lugar de esto abandona al p d r y el núcleo coloca su bloque de curztr-01 hasta que lo despieata el núcleo, el cud saca al proceso de la lista de bloqueados y lo coloca en la lista de listos.

* I

Page 80: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Las operaciones de semcfforos pueden ser también i m p 1 e m e a t a - h en el nkko, para evitar la espera de ocupado. Un semdforo se implementa como una mriable protegida y una cok en la cual los procesos pueden esperar por las operaciones Y:

Cuando un proceso intenta una oprucih P en un semiforo cuyo valor actual es cero, el proceso abandona. al procesador y se bloquea a sí mismo para esperar por una operad& Yen el ser@foro. El n&&o coloca el bloque de control de procesos en la cola de procesos que esperan en ese sedforo ( se supone que hay ma disciplina de colas del primero-en- atm”primero-a-saíir. Se han investigado otrasdiscípIims,induyendo la cola prioritaria). El ndcZeo, entonces, reasígna el procesador al siguiente proceso de listo.

El proceso em la cola del sentcfforu acaba por avanzar a la cabeza de la d a . Eintonces, la siguiente opsracidn Y saca el proceso de la cola y lo coloca ea la lisa de listos. Por supuesto, a los procesos que mtent8n operaciones s i m . u l t $ n e a s P y Y, el núcleo les garantiza el acceso exclusivo al semiforo.

La comunicación curno ya se dijo, es otro concepto estrechamente ligado con la sincronkción y consiste en la forma de como los procesos intercambian informacibn. Existe una gran variedad de mecanismos de s í n h e ó n y comunicaci6n: las variables glabales comprtkks no protegtdas, 10,s sermfforos, los mensujes, hs trayectorias @ath qpressions), los eventos, krs corutinas, hs re@ones cr&cas condicionales, los monitores y los mcuentros (rendernous), entre otros.

Unlenguajetieneque ofiecer los medios de protección contraemores que dependen (del tiempo. Hay variw sintaxis de lenguaje que han sído propuestas para. tratar estos problem, a s í como los de la comunicacih y sincronización antes mnmcímados:

Page 81: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

2.3.3. Regiones C r i t i c a s .

Pueden utilizarse pars implementar la ewZwi6n mutua de numera segura y eficiente. I” sd furos pueden utihzme de manera eféctiva para la resolución del problema de la seccic5n crfticu. Todos los procesos comparten una variable de tipo s&foro rnhtex, inicializada a 1. Cada proceso tiene que ejecutarP(m&a) antes de tmtrar a la secci&n crítica, y V(rnz2tex) al salir. Si no se observa esta secuencia, puede haber dos procesos en sus secciones críticus simd&-ente, de lo que resdtsrfan errores dependientes dell tiempo.

Extminmm l a s dificultades que 1Puede;n presentarse, dificultades que aparecerstl mcl~uso si un sólo proceso no se comportacorrectamme. Estasituaciónpdeser el resultado de un simple m r de pmgmnacibn accidental o bien de un programador poco e s c r u p u l o s o .

- Supongamos que un proceso invierte l a s operaciones sobre el sem&foro mútex. esto es, ejecm

... secciitn critica ...

P(mÚtex);

En esta situación, varios pjrocesos pueden estar ejecutando simultsneamerrte en su seccibn crttica, violando el requerimiento de excZud&n mutua. Este error dependíente del tiempo &Io puede ser descubierto si hay simdtáneamente varios procesos activos en sus secciones crtticas. Obsérvese que esta situación puede no ser siempre reproducible.

- Supongamos que un proceso cambia V(mtsfex) por P(mtstex). Esto es, ej-

Page 82: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

P(mútex);

Ein este caso se producírá un abrazo mortal.

- Supongamos que un proceso omite P(m&exc), V(mzíta) ó a m b o s . En este caso, o bieax se violará la exlwicin m u m o se producirá un abraw mortal.

Ei ejemplo anterior ilustra d m 0 pueda perame f e e n t e errores que dependan del tiempo cuando se d o r o s para resolver el problema de la seccidn &a. :Para superar ésta deficie3lcia Brinch Hansen y Hoarce mtrodyeron un nuevo constmcto en el lenguaje, la regic5n &m. Una variable v del tipo T, compartida entre muchos procesos, puede ser declarada ask

La variable v d o puede ser accedida dentro de una imtruwión región de lasiguiearte f o m

región v do S;

Este mnstmcto sipficaque mientras la instruccicin S está siendo ejedada, ningim otro proceso puede acceder a la variable v. Así, si las dos msbnrcclones:

región v do S1;

región v do S2;

se ejecutan concurrenkmente en distintos procesos secuenciales, el d t a d o será equivalente a la ejecwiirn secuencial de "SI seguido por S2" ó "S2 seguído por SI".

Page 83: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

El mecanismo de la rsgibn crftr"ca evita algunos errores sencillos relacionados con la solución del semifir0 al problema de la sem'dra crítica, reahable por un programador. Obsérvese que no eliminanecesariamente los mofes que dependen del tiempo, sino que más bien reduce su número. Si se p d u c e n errores en la lógica de un propma, la reproducción de una secuedlcia de s u m s determinada puede noradtar sencilla

Ilustremos como un cornpilador podría implementxu la secd&n critica. Para cada declaración

el cornpilador pera un semciforo twzt5tex inicializado a 1. Para cada instrucció&

regiirn v do S;

ei compilador pera el siguiente &digo:

La sncltrsidn mutua queda claramente preservada por la semántica de la instnrccón de rtgidn dtica.

Las regiones miticas también pueden utdizmse anidadas. Ea dido caso es f k d que se praduzcan abrazos mo~akks. El siguíente programa ilustra esta situación.

v a &y:sh€Jred 1:; P h *

Q:region x do region y do S1; Rregion y do region x do S2;

pare&

Page 84: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

TO : Q ejecuta P(x-mútex). TI : RejecutaPOI-mritex). "2 : R ejecuta P(x-mirtex), R espera mientras x-mútex = O. "3 : Q ejecuta P(y-mútex), Q esperra mientras y-miitex = O.

2.3.4. Regiones Cxí t i ca s Condicionales.

La regidn crftica puede utibrse de mera efectiva para resolver el problemadeIasceccidn crítica. No obstante, no puede usame para resolver algunos problems perales de sinuu-¿jn. Por esta dn, Hare introduce 1a regr'dn crítica condicional.

region v when B do S;

donde B es una expresibn booleana. Como antes, 18s regímes que hacm refixeacia a la misma variable compartida se excluyen unas a otras en el tiempo. No obstante= ahora cuando un proceso entra en la regih de la seccih critica, se evalúa la expmsihn booleana B.

Page 85: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Si la expresiiin es cierta, se ejecuta la sentencia S. Si es fálsa, el procesodesisfe.JIesdemoradohastaqueBsehagaciertay no existaotro proceso en la regiirn asociada a v.

203.401,. Problema del btif f er 1 i m i t ado.

IIustremos estos conceptos codificando el problema del bMkr limitado.

EI espacio para b M m y sus apuntadores esth enqsulados en:

El proceso productor inserta un nuevo i t e m nextp ea el bd@iir ejecutando:

region buí€= when count n

pool[m] := nextp; im:=in+ 1 modn; cxlunt := comt + 1;

do begin

end,

El proceso conmcmidor elimina un item del bdflr compartido y I nexfc ejecutando:

region buf€br when comt > 01 do begin

nexk := pool[out]; out:=out+ 1 modn; counf := count - 1;

en&

Page 86: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Verunos como podria ser implementada por un compilador la regidn crftica condiciOrza2. Asociando a cada variable compartida x, teardremos l a s sigUie!ms variftblles:

var x-:mutex, x-wait: semaphore; xco- x-temp : inteF,

x-mutex es quih fdta el acceso en exclusidn mutua a la secddn crítica. Si un proceso no puede eatrar en su secdt5n crftica porque la condición booleana B es Msa, espera en el d o r o x-wait. Seguimos la pista de un cierto número de procesos que esperan en x-wait y en x-count. Cuando un proceso deja la seccidn Wcu, p&e haber cambiado el valor de alguna condición booleana B que impedía que otro proceso entrara en la sección crítica. Por tanta, tenemos que seguir lia cok ds procesos en espera de x-wait permitiendo que cada proceso verifique su condición booleana. Utilizamos x- temp, para determinar cuando hemos permitido a cada proceso que verifique su condición. C o ~ ~ t e m e n t e , x-m- se inicializa a I , mientras que x- wait, x-count y x-temp se inicializan a O.

Una sentencia.:

region x whea B do S;

puede implemeartarse como sip:

P(x-mukx); ifnot B them begal

x-cmmt := x-count + I; V(:x-mutex); P(X-wait); while not B do begin

x-temp := x-temp + 1; if x-temp x-count then

V(x-wait); else V(x-mutex);

P(x-wait);

Page 87: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

ifx-coun.t > o then begin

x-temp := o; V(x-wrait); end;

else V(X-XYN&X);

Esta implemeatación supone una ordenación HFO en la cok de procesos de m semrffaro.

Obsbese que esta implementacih requíere evaluar la expresión B para cada proceso en espera cada vez que M proceso sale de la regid# crítica. Si se retrasan varios procesos esperando que sus expresiones booleanas respectivas sean[ ciertas, esta sobrecarga de evaluaciónpuedecunvertir el ddigo en indiciente. Hay varios métodos deoptimizaciónutitizables para reducir esta sohremrga

El constmcto de Huure pemnte que los procesos sean demodos solamente al ]principio de una regidn cr í t i ca . Sin embargo, hay circunstancias m l a s que las condiciones de sincronización timen que ser situadas ea CuBYquier l u g a r dentro de la seccidn c r f f i c a . Esta observación condujo a Brinc:h al siguiate constructo de rq#n:

region v do begin s1; await@); s2;

a 4

Page 88: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Cuando un pt'oceso entra en la región, ejecuta la instnrcción S1 (S1 puede ser nula) y evalúa B. Si B es cierta, se ejecuta S2, si B es fálsa, el proceso desiste en la eJeclusidn muiua y se retrasa hasta que B sea cierta y no haya otro proceso en la r e ó n asociadr a v.

Este nuevo constnrcto lo ilustramos &cando una varimte del segundo probkim de los &ctor8sksm~t~r8s. hi problema exige que una vez que un escritor esté prq,arado, pueda escribir lo antes posible.

2.3.4.2. Problema de l o s lectoreslescritores 11.

Así, un lector S610 puede entxar ' e n su seccidn crttica si no hay escritores esperando en su seccidn crítica.

La regidn crítica condicional se umbina con nuestro construct0 de clase descrita anteriormente:

type reader-writer= class varv:shart%irecord

nreders, nwriters : integer; busy : boolean;

end;

Page 89: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

procedure entry open-write; region v

do be:+ nwriters := nwriters + 1; awaJt((not busy) and ( d e = = O)); busy := true;

m&

procedure entry closewrite; region ‘u

do begin nwiters := Nwriters - 1; busy := false; en&

besrn busy := fithe; nreaders := O; nwritem := O;

end.

2 . 3 . 5 . . Monitores.

Fmlas secciones p d e n t e s hemos descrito los mecanismos de implementacibm de l a s primitivas de exclusidn mutua con el algorim de Deltker y los sedforos de Djkstra pero éstos m M o s tienen varias debilidades: son tan primitivos que: es dificil expresar la solución de problemas de concurrencia más wmpkjos, y su presencia en los prugrarnas concurrentes dificulta aún más el problema de probar la correccibn de programa El wso incorrecto de estas primitivas, ya sea mknúonado o accidental, podría mrrompex la operación de un sistema conmente.

Page 90: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

- fidten probar la correcciiln de problemas.

- multe muy dificil (cuando no imposible) su uso mcorrecto 6 corrupción por p t~ te d e l usuario.

Por esto, el deseo de oft- cwtodcammte la sincronizacii6n apropiada condyo aBrhch Hamen y aHoare al: desarrollo de un nuevo construct0 de lenguaje : el monitor.

Un m ' t o r es Un8 construcckh de concurrencia que contime 10s y p d d o ~ r necesarios ara redizar la asignsci6n de un compartido detemido, o de un grupo de reamos comp8ffidos. para cumplir con la fimubn de asi@bn de recurso, un proceso debe llamar a d e al monitor. MUCIIOS procesos p e mar de 81 monitor en diversos momentos. Pero la sxclusidn m u m es aplicada rígidamente en los límÍtes del monitor. Sólo se pennite la entrada a un proceso a la vez. Los procesos que deseea entrar cuando el monitor está en uso deben esperar. La espera es a d m i de forma automática por el monitor. Como la exclusidn mutw está se evitan l o s desagradables problemas de concurrencia coma los resultados indeterminados

Page 91: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Los datos contenidos en el monitor pueden ser globales, para todos los procedimientos dentro del monitor, o locales, para un procedimiento específico. Todos estos datos sólo son accesibles dentro del monitor; no hay forma de que M. proceso de hera del monitor pueda accesar a sus datos. Esto se llama encubrimiento de informucidn, una técnica de atructuración del sistema que f d i t a en gran medida el desarrollo de sistemas de software más confiables.

Si el proceso que llama a la entrada al monitor encuentra que el recurso ha sido asignado, entonces el procedimiento del monitor llama a wait ( espru ). El pnxeso podría permanecer dentro del monitor, pero esto violaría la e;lcclusidn mutua si en este momento entrara otro proceso al monitor. Por tanto, al proceso que llama a wait se le hace esperar hera del monitor hasta que el recurso sea liberado.

El proceso que tiene al recurso llamará finalmente una entrada al monitor para devolver e l recurso al sistema. Esta entrada tan sólo aceptaría el recurso de regreso y esperaría la llegada de otro proceso de petición. Pero puede haber varios procesos esperando por el recurso, a s í que el monitor llama a signa2 [( seffal ) para p&tir que uno de los procesos en espera adquiera el recurso y sdga del monitor.

Si un proceso seiiala el regreso (algunas veces llamado liberación) del recurso, y no hay o h esperando, entonces la seÍíaI no tiene efecto alguno (pero el monitor ha recapturado el recurso). Está claro que un proceso que espera un recm debe hacerlo firera del monitor, para permitir que otro proceso dentro del monitor regrese el recurso.

Para asegurar que un proceso en espera de un recurso acabe consiguiéndolo, el monitor le otorga prioridad sobre m nuevo proceso que pida entrar al monitor. De otra manera, el nuevo proceso toma el recurso antes de que el que esta en espera vuelva al monitor. Si ésta desafortunada secuencia tuviera lugar de forma repetida, entonces un proceso en espera sería postergado indefinidamente.

Page 92: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

A s í , un Monitor es un mecanismo que permite la compartición segura y efectiva de tipos abstractos de datos entre varios procesos. La sintaxis de un monitor es idéntica a la de una clase, salvo en el hecho de que la palabra clave class es reemplazada por la palabra clave monitor. La principal diferencia semántica es que el monitor asegura la exclusidn mutua; es decir, sólo puede haber un proceso activo dentro del monitor al mismo tiempo. Esta propiedad la garantiza el propio monitor.

Consecumtmente, el programador no tiene que codificar explícitamente éSta restricción de sincroniz(clci&n.

El monitor, como se ha definido hasta ahora, es en muchos aspectos similar a la regidn crftica. Como é&a no es suficientemente potente para modelizar ciertos esquemas de sincronización, ha sido ampliada a la regi&n crítica condicioml. Análogamente, para la sincronización con monitores necesitamos mecanismos adicionales. Estos mecanismos nos los ofiece la construccidn condition (condicidn). Los programadores que necesitan escribir su esquema de sincronización. a medida pueden definir una o más variables del tipo condition:

var x,y : condition;

De hecho, las procesos podrían desear (necesitar) esperar fuera del monitor por varias razones. A s í que por esto se introdujo la noción de una variable de condición. Se asocia una variable de condición individual a cada una de las ' m n e s por las que un proceso puede necesitar esperar. Las operaciones wai,ty signal son entonces modificadas para incluir el nombre de la variable de condición que se esth esperando ó seiialando.

wait(nombredelavariab1edbledecondicion) signal(nombredelavariab1edmndicion)

Page 93: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Las variables de condición son muy distintas de las "convencionales"' con las que estamos fdarizdos. Al definir una variable de condición se establece una cola Un proceso que llama a wait se asocia a la d a y un procleso que llama a signal provoca la extrawith de un proceso en espera de la cola y su entrada al monifor. Puede darse por sentada la existencia de u n ~ a disciplina de colas del primero-en-ebztrar-primero-en-salir, aunque los esqutzms de prioridades pueden ser Mes en algunas situaciones.

Las únias operaciones que se pwedm realizar sobre una variable de condici6n son rwit y signal. Así, ma variabie de condicibn puede entenderse corno tipo abstracto de datos con estas dos operaciones.

La operación

sigmfica que el proceso que invoca 18 operaeih queda bloqueado hasta que otro proceso invoque

La operación x.signa2; reanuda un proceso bloqueado. Si no hay ningún proceso bloquedo, la operación sigrud no tiene efecto; es decir, el estado de x queda como si la operación signa2 no se hubiera ejecutado. Esto contrasta con la opructh Y; que afecta siempre al d o del semdforo.

Ahora supongamos que cuando se invoca la operación xsignal; por un proceso P, hay M proceso bloqueado Q asociado con la condición x. Evidentemente, si el proceso Q recibe autorización para reanudar su ejecución, el p~oceso invocante P tiene que aperar: Ein caso contrario Py Q dan activos simultáneamente dentro del monitor. Obsérvese que ambos procesos podrían conceptualmente continuar con su ejecucibn.

Hay dos posibikidades:

u. P espera hasta que Q o bien abandone el monitor, o bien espere en otra condición.

Page 94: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

b. Q espera hasta que P o bien abandone el monitor, o bien espere en otra condición.

Hay argumentos nuonabks tanto en favor de (a) como de (5). Puesto que P ya se estaba ejemtando en el monitor, la elección (6) parece más razonable. Sin embargo, si permitimos que continúe el proceso P, la condición "lógica" por la que Q estaba esperando puede ya no se cumpla cuando Q se remude.

Hoare ha elegido la opción (a), principalmente porque el argumento anterior en su favor se traduce directamente en pruebas de reglas más elegantes y simples. Brinch Hansen, por otra parte, eligió una solución de compromiso,. Cuando el proceso P ejecuta la operación signal, deja inmediatamente el monitor. De qui' que Q se reanude inmediatamente. Este esquema es menos potente que c d de Hoare, pues un proceso no puede ejecutar signal más de una vez durante una llamada a un procedimiento.

2.3.5.1. Ejemplo monitor: sema'foro binar io .

Se ilustran estos conceptos escribiendo un monitor que simule un sem&foro binari'o:

type semaphore = monitor var busy : boolean;

nonbusy : condition;

procedure entry P; begin

i f busy then nonbusy. wait; busy := true;

end;

procedure entry V;

busy := false; nonlbusy.sipal;

begin

end;

Page 95: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

begin

end. busy := fdse;

La variable biooleana busy (ompdu) indica el estado del semíforo. Cuando se ejecuta la primera operacion P, es estado del se&forow actualiza a ocupado; si se intentacualesquiera operaciones P adicionales, &os procesos ten& que esperar hasta que tenga l u g a r una opera&& Y: Obsémese que la oprucidn Ysiempre actualiza busy a falso. Si hay un proceso en espera, inmediatamate restam busy a cierto. Si no hay procesos esperando, busy permanece en falso.

2.3.5..2. Ejemplo moni tor: La comida de f i l d s o f o s .

Consideremos M ejemplo más complicado, el problema de la comida de flldsofos. Presentamos una soluci¿"n exenta de abrazos mortales permitiendo que unfik~sofo coja sus palillos solamente si ambos están libres. Para codificar esta solución, necesitamos distinguir entre tres estados en los que puede encontrarse un filósofo;. pnsundo, comiendo 8 hambriento (thinking, eating, hwrgryl. Con este propósito, introducimos la siguiente estructura de datos:

v u state:arrsy[O..4] of (tiirdcbg, eating, hungry)

El filosofo i puede fijar state[i] := rating solamente si sus vecinos no están comiendo (esto es, Me[i-I mod 51 0 eating y state[i+l mod S] 0 eat ing. También podemos declarar:

var seKarray[0..4] of conditicm; en la que el filósofo i puede retrasme a sí mismo cuando está hambriento pero es incapaz de obtener l o s pdillos que necesita.

Ahora estamos en condición de exponer nuestra solucicln. La distribución de los palillos es controlada por el monitor:

type dining-philosophers = monitor var state : -[O. .4] of (thuhng, hungry, eating); var self : m y [0..4] of condition;

Page 96: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

procedure entry pickup(i:O. 4 ; begin stateri] := hungry; test(i); if state[i] c+ eating then semi]. wait;

end;

PrOCedrlre enby putdown(i:0., 4); begin state[i] := thinking; test(i-I mod 5); test(i+l mod 5); end;

procedure test(k:0..4); begin ifstate[k-I mod 51 0 eating

and state[k] = hungry and state[k+l mod 51 0 a&ng then

begin state[k] := eating, sel:qk].singal;

en& end;

begin for i :== 0 to 4 do statel[i] := thinking;

end.

Page 97: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

dp.pickup(i); ...

come dp.putdown(í);

Es fkil demostrar que &a solucibn gamntua que no hay v e o s wmkndo s~ult$neamente y que no se producírá un abrazo mortal. sin embargo, O ~ ~ O S que es posible que un filósofo entre en inanición hasta morir. No se presenta un8 solución a este problema

2-3.5.3. Implementación del monitor,

Ahora consideramos una posible irnplemeatslcih del mecanismo del monitor. Para cada monitor hay M sermíforo mutex (inicializado a I). P(mutex) time que ejecutame antes de entrar en el monitor, mientras que V(mut.) tiene que ejecutarse desp& de abandonar el monitor. Puesto que M proceso que invoque s i g n a 2 time que esperar hasta que el

proceso reanudado salga o bien espere, se introduce M semtforo adicional, next, inicializado a O, con el que los procesos que invocan pueden bloquearse a sí m h o s . Una variable entera next-count cuenta el ntimero de procesos bloqueados ante next. Así, cada procedimiento externo F será reemplazado por

P(mutex); ...

cuerpo de F; ...

La exclusidn mutua dentro del monitor queda garantmacia Ahora podemos describir c6mo se implementan las variables de

condición. Para cada condición x introducimos un semiforo x-sem y una variable entera x-count, ambos inicializados a O. Ahora, la operación xwuit puede implementarsie como:

Page 98: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

x-count := x-count + 1; ifnext-count > O then V(next) else V(mutex);

P(x-sa); x-count := x-count - 1;

La operación x . s i p 2 puede implementam como:

ifx-cuunt > o then begin nat-count := next-count + 1; V(x-sem); Pcnext); next-count := next-count - 1;

end;;

Esta implemmtación es aplicable la definición de monitor, tanto a la de Hoare como a la de Brinch Humen. Sin embargo, en algunos casos la generalidad de la implementacih no es necesaria y es posible una mejora signtficativa en la eficiencia

Obshese que si un monitor M1 llama a otro monitor M2, la exclusión mutua en M1 no se abandona mientras se procede a la ejecución deM’! Este hecho tiene dos consecuencias:

- Cualquier proceso que llame a M1 quedará bloqueado f k a de M1 en mutex durante este período de tiempo.

- Si el proceso entra en una cola de condición en M2, puede producirse un abrazo mortal.

Este problema recibe el nombre de problema dc3. kas llamadas a monitor anidadars.

Page 99: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Ahora volvamos al tema del orden de reanudación de procesos. Esto es, si hay varios procesos bloqueados ante la condición x y se ejecuta una operación x.signa2 que proceso es el que se reanuda a continuación?. Un esquema !sendo consiste en utilizar e lJ irs t~~~e-~rs t - ssrvsd . Así, el proceso que espera desde hace mhs tiempo es el que se reanuda primero. Sin embargo, hay mudm circunstancias en l a s que M esquema de planificación tan simple no es adecuado. Por esta d n Houre introdujo la sentencia condiitional wait (espera condicional).

Tiene la forma:

x. wait@);

donde c es una expresión entera que se evalúa al ejecutar la operación wait. El valor de c, que recibe el nombre de número de prioridad, se ahacena junto con el nombre d d proceso bloqueado. Cuando se ejecutax.signa2, el proceso que tenga asociado el nhero de p:riondad más bajo es el que se remuda primero. Ilustremos este nuevo mecanismo desarrollando un algofitmo de planificación que asigna un recurso en orden shortest-job-first. Suponemos que cumdo cada proceso solicita una asipacion, especifica el tiempo máximo durante el que tieneintención de utilizar el recurso.

2.3.5.5. Algor i tmo de p l a n i f i c a c i 6 n .

type SJN = monitor var busy: boolean;

x: cxndition; prmsdure entty acquire (time : integer);

begin iqbusy) then

x. wart(he); busy := true;

procedure entry release; ell&

begun busy := false; x.si&; end;

Page 100: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

begirk busy := f d s e ; e n d .

Ear los lenguajes centralbdos oriea~tados a objetos como SmllTalk, las operaciones se realizan a través de mensajes. En la programacidn conamente la idea de memaje conlleva cierta noción de lejania y de distribución del procatmiento. A pesar de estas diferencias hdammtales l e s posible conciliar ambos doques introduciendo la idea de objetos remotos. Un objeto remoto se puede considerar como una exteasón a la3 formas de almacenamiento de variables que ofiecen l o s l e n g u a j e s de programación como C:, ya que el objeto reside en otra computadora cuya ubicación puede ser desconocida para el programador. De esta forma, la sintaxis de las declaraciones de este tipo de objetos no cambia demasiado y la semántica de l a s operaciones toma M sentido que concuerda con la noción de llamada a un objeto remoto. Aquí, el procedimiento remoto Corresponde con un procedimiento público que o h el objeto remota. El intercambio de información de los parámetros y los resultados se realiza en ambas direcciones durante la comunicación de los procesos. Debe observarse que un objeto remoto podría encontrarse en la misma máquina que el invocador si a s í se desea, lo que conciliaría las difaencias.

2.4. E a c i l i d a d e s d e l l e n g u a j e .

A la mayoría de l o s lenguajes de programacibn secuenciales se l e s considera de propósito peral, aún cuando dificilmente poseen l a s caracteristicas r ~ e c e s a r i a s para resolver cualquier tipo de problema, especialmente de aquellos que involucran concurrencia.

Las caracteristicas de los lenguajes concurrentes pueden enm- de acuerdo a las fididades que se brindan para:

a. Ejecucic5n no determinfstica. Una caracterf&ca que debe poseer un lenguaje de prt~gramcibn conmrre4nte es el no detemtinismo en la ejecución de un programa Esto significa que un programa que corra dos veces con los mismos valores en la entrada puede producir dos salidas

Page 101: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

distintas. Algunos lenguajes poseen estatutos especiales para la formulación del. no detenninismo. En. otros, el no determinism0 aparece por la intervmcibn del adminisirador de procesos.

6. Compibcibn sepra&. El lenguaje debe ofrecer la posibilidad de compilar M mbdulo sin tener que k l o para el resto del programa Se deben ofiecer especificaciones de clasts y de funciones a otros moddos pura la verificación estricta de tipos.

C+ soporte a aplicaciones de tiempo real. El lenguaje debe o+ facilidades para escribir aplicaciones de tiempo real y de control de procetsos que sean confiables y eficientes. Debe otorgar al programartor el control pleno del orden en que los procesos se deban sincmnizar. Otra caracteristica que requiere este tipo de aplicaciones es el concepto dejin ds pkw (timeout) en la comunicaciivn de procesos. Un proceso que enviarun mensaje y espera una respuesta debe tener en cuenta la posibilidad de situaciones excepcionales que impidan el logro de la transacción. El pr-oceso puede caer en un círculo vicioso a menos que se h í t e el tiempo de espera de la respuesta El jin alel plazo se puede considerar dentro del manejo de excepciones.

d Manejo de cexcepciones. El lenguaje puede permitir definir acciones que tienen l u g a r en caso de que ocurra alguna condicih excepcional o algún error, El mando correcto de las ezrcepciunes puede evitar l a s caídas del sistema aplicando d o n e s correctivas.

e. Venfjicaci&n Cde programas. Los programas concurrentes son mucho más dificiles de verificar que los programas secuenciales. El lenguaje debe asistir al programador para determinar la congruencia del código entre los valores de entrada y de salida.

Page 102: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

distintas. Algunos lenguajes poseen estatutos especiales para la formulación del no detemruus mo. E n . otros, el no determinism0 aparece por la hkweación del administrador ds procesos.

. .

b. Compilucidn separada. El lenguaje debe ofrecer la posibilidad de compilar M m¿iddo sin tener que hacerlo para el resto del programa. Se deben ofrecer especificaciones de claws y de hciones a otros módulos pura la verificación estricta de tipos.

c. Soporte a aph'caciones de tiempo real. E1 lenguaje debe o h r facilidades para escribir aplicaciones de tiempo real y de control de procesos que sean confiables y eficientes. Debe otorgar al programador el control pleno del orden en que los procesos se deban sincm&. otsa caracteristica que requiere este tipo de aplicaciones es el concepto defin de phzo (timeout) en la comunicacit5n de procesos. Un proceso que envia. un mensaje y espera una respuesta debe tener en cuenta la posibilidad de situaciones excepcic~nales que impidan el logro de la transacción. E1 proceso puede caer en un círculo vicioso a menos que se limite el tiempo de espera de la respuesta. El fin del phzo se puede considerar dentro del manejo de excepciones.

d. Manejo de acepciones. El lenguaje puede permitir definir acciones que tienen lugar a1 caso de que ocurra alguna condición excepcional o al& mor. El manejo correcto de las excepciones puede evitar las caídas del sistema aplicando amiones c0nectiva.s.

e. Ven$cacicSn de programas. Los programas concurrentes son mucho mis dificiles de verificar que los programas secuenciales, El lenguaje debe asistir a l programador para determinar la congruencia del código entre los valores de entrada y de salida.

Page 103: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

B . L E N G U A J E S

C O N C U R R E N T E S

Page 104: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

1. INTRODUCC16N.

El concepto de programación concurrente ha sido apreciado desde los primeros días del surgimiento de la computación, pero la tecnología para desempeñar y soportar un paralelismo en hardware se puso a disposicih desde los últimc)s diez años, por esto surge la idea de construir l e n g u a j e s que tengan la potencialidad de manejar y soportar la conclurencia

Las computadoras son empleadas principalmente para modelar el mundo real. Algunos problemas consisten de una serie de acciones primitivas, l a s cuales pueden :ser ejecutadas una tras otra, en secuencia Sin embargo, el mundo en el que vivimos se compone de actividades, inherentemente paralelas ó concurrentes.

De esta manera, se han creado y encontrado formas de simular eventos concurrentes a través de una serie de primitivas, con el fin de modelar el mundo con una computadora convencional. Sin embargo, podemos apreciar un serio problema cuando se trata de controlar tareas en relacibn con eventos que s u d e n en tiempo real, o cuartdo se requiere de una coordinación especial de procesos; entonces, este tipo de computadoras se vuelven simplemente, inoperantes.

De esta manera surgen los lenguajes de programación concurrenfe que son herramientas que permiten una concurrencia que puede modelar el mundo real, pudiendo, mediante la incorporaciirn de direztivas nuevas, hacer programas conamentes, que permitan den solución a muchos problemas que son en esencia concurrentes.

Revisaremos ahora los lenguajes más conocidos que tienen incorporados mecanismos para la sincronización y comunicación entre procesos, y que obviamente son concmentes. Estos lenguajes varían en la forma de soportar las primitivas de comunicación. Por ejemplo, el Concurrent PaslcuZ emplea el paso de p h e t r o s , el CSP el paso de mensajes y ADA una combinación de ambos maodos.

Page 105: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

2. CONCURRENT PASCAL.

2.1. Introduccidn

Concurrent Puscul es un lenguaje de programación diseñado para la programación astructurada de sistemas operativos. Desarrollado por Brinch Hansen, se basa. en el lenguaje secuencial Pascal. Uno de los aspectos más relevantes del Concurrent Pascal es que soporta la modularidad en la construcción de programas. Un sistema programado en este lenguaje se w e e a pmtir de tres tipos de módulos:procesos, clases y monitores.

Los procesos son secuenciales y no comparten ninguna variable. Las clases SOR tipos abstractos de datos; cada clase puede ser accedida por un proceso y sólo uno. La comunicación entre procesos tiene que realizarse por me&o de monitores, Concurrent Pascal fué el primer lenguaje concurrente en usar monitores. Los ,monitores del Concurrent Pascal son similares a los descritos anterioxmente, pero con las sigutentes diferencias:

- Las variables de condición (Ilamrdas cohs en Concurrent Pascal) sólo pueden tener una irnica entrada Si tios procesos tratan de entrar en una situación de bloqueo ante la variable de condición, se produce un mor.

- Cuando un proceso invoca la operación signal sobre una cola, se reanuda un proceso bloqueado ( si lo hay) e inrnediatamertte abandona el monitor. Estas chferencias se traducen en la generación de un código mis eficiente

por el cornpilaclor. No obstante, restringen el tipo de propmas que podemos escribir. Por ejemplo, no es posible invocar signal dos veces dentro de un prolcedimiento monitor.

El Concurrent Pascal va bastante más allá de la simple provisión de un mecanismo mediante el que se pueda compartir con seguridad un segmento de datos. Solamente lo permitirá si ese segmento ha sido declarado dentro de un monitor. LA semántica de1 lenguaje no permite que un programdor declare una insstancia de un tipo de datos compartido de cualquier otra manera

Page 106: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

El Concurrent Pascal ( d Pascal Concurrente), soporta ampliamente el disefío de programas fiables restringiendo la complejidad de l a s estrategias de gestión de recursos. El lenguaje no permite procedimientos recursivos ni la defínici6rn de tipos de datos recursivos. En consecuencia, todo el almacenamientc~ principal puede asignarse estáticamente en la compilación. Todos l o s componentes de un programa (instancias de procesos, c h e s y monitores) se crean por declaración y son permanentes. Finalmente, l a s variabks de condición (colas) sólo pueden tener una entrada La utilidad de un mecBnismo tan restrictivo incluido en un lenguaje de alto nivel tiene que ser demostrada por su adopción en la práctica. Sin embargo, existen al menos dos argumentos poderosos para su USO:

Un programador que irnplmente 'un sistema con Concurrent Pascal no tiene que preocuparse sobre los errores intemitentes que a veces suceden por una incorrecta sincronización de l a s variables compartidas.

2 . 2. E s t r u c t u r a de l o s programas de Pascal Concurrente.

Un programa de Pascal Concurrente consiste de mas series de "componentes de sistema" definidas en su propio espacio de direccionamiento. Por deMG todas las variables son privadas, y el programador delbe definir explícitameate las posibles rutas para comunicación ó interacción.

Un progrmm de Pascal Concurrente está compuesto de tres tipos de componentes de: sistema, como ya se dijo:

a. Procesos. Corresponden ampliamente con el concepto de un proceso introducido antes, en este documento. Los procesos consisten de variables localas que son privadas a los procesos y el coljunto de sentencias que operan en &e. El proceso es la parte activa del sistema

b. ~ 0 n . i tores. Proveen ell únice medio por el cual los procesos pueden coordinar su operación. La estructura de un monitor es s d a r a la de M proceso, el cual consta de variables privadas y procedimientos por los cuales &os pueden ser accesados.

Page 107: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Un monitor es un objeto pasivo el cual es manipulado por aquellos procesos que desean Ilmw a los procedimentos que maneja el monitor.

c. Clases . Son similares 8 los monitores y proveen estructuras de datos abstractos consisteates de datcts y procedimientos. Las resbricciones de l a s clases en su definición y uso consisten en que nunca sedn accesibles a más de un proceso a la vez, por el establecimiento de la exclusión mutua inherente al lenguaje. El principal propósito de una clase es la optimización del programa

Por defhít, los procesos no tienen acceso a un monitor. El permiso para hacerlo debe estar explícito en sus d e d o s de acceso.

Pascal Concurrente d basado extemivamente en el Pascal est&n&r y la estructura de la definición de los procesos y monitores es muy similar a la defínición de 1.0s procedimientos. I a s pueden contener defhciones de constantes y tipos, declaraciones de variables y procedimientos, y son concluidos por una secuencia de declaraciones y sentencias. Una limitacih del lenguaje l e s la falta de variables tipo apuntador y llamadas a procedimientos recursivos. Estas restricciones permiten tener a un componente dc sistema los m h o s requerimientos de almacenamiento requeridos durante la compilación para el adecuada área de memoria, cuando éstos son inicializados. Esta política quita los problemas de almacenamiento d i n á m i c o . La secuencia final de declaraciones de un monitor puede ser usado para inicializar. sus variables antes de que sean accesadas por otros componentes de sistemK en un proceso l a s declaraciones definen su propia operacibn.

Dentro de un monitor, algunos procedunientos ó funciones pueden ser defínidos coma rutinus enfry. Estas rutinas pueden ser llamadas por otros componentes de sistema, pero éstas no son accesibles desde dentro del mismo monitor. El sistema a tiempo de 2jecucidn forza la exclusidn mutua de l a s entradas a un componente de sistema

Page 108: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Las definiciones de procesos y monitores pueden ser parametrizadas en una manera aniloga a las definiciones de parámetros de procedimientos. Las dehciones de pmármtros consisten de una secuencia de nombres de variables y sus correspondientes tipos; valores apropiados deben ser provistos cuando se inicializa un componente. Un parámetro debe ser identifwd0 como una variable simple que requiere un valor constante para su inicialización ó valor inicial. Un parámetro referente a un tip monitor debe ser inicializado con una referencia al monitor del tipo especificado. Los parámetros provistos especifican los derechos de acceso a otros componentes de sistema Un procexhmiento tipo entry con parámetros debe ser invocado especdicando su nombre y el de ambos parámetros. conectados por un punto (.). Los parámetros del procedimiento se dan en la forma usual. es decir,

<nombre - monitor>.<nombre~rocedímiento>(<parámetros-actualet);

2 . 3 . La e s t r u c t u r a de una s o l u c i d n del c a m a r k p r o b l e m b a s a d a en m o n i t o r , se da a c o n t i n u a c i ó n .

El curpark problem considera un sistema de control para un estacionamiento con un número de entradas y salidas que son controladas por barreras automaiticas. E¡ propósito del sistema es controlar el flujo de vehículos en el estacionamiento viendo que siempre halla un l u g a r de estacionamiento disponible para cada vehículo que en-

Este es un tipico problema de buscar l u g a r donde los procesos controlan l a s entradas completamente del estacionamiento y los lugares disponibles para controlar el acceso de los vehículos cuando halla lugar.

La variable spaces está contenida en un monitor space - control con dos procedimientos entry:

space: - control = monitor; consst

max spaces = 100;

spaces : O..max - spaces; V a

-

Page 109: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

procedure entry arrive; aegin

spaces := spaces + 1; end; procedure entry depart; begin

end; spaces := max - spaces;

La solución simple ignora el problema de qué es Io que pasa cuando el carpark está lleno, pero ilustra la estructura de un monitor. Nótese que la inicialización de spaces está en la declaración hal. Este monitor puede ser accesado por procesos controlando la5 compuertas de entrada y salida:

entrance - control = process(taI1y : space - control);

begin cycle

<await customer>; a y . arrive; <admit - custom-;

-

end; end; { entrance - control 1

exit control = process(tal1y : space-control); be& cycle

<detect leaver>; tally. depart; ~dismiss:leavc=r>;

-

end; end; { exit - control 1

Ambos procesos tienen acceso al monitor e invocan a sus procedimientos para actwhar Irs variable común spaces. La construcción;

cycle

end <secuencia ” de sentencias>

Page 110: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

indica la repetición indefinida de sus sentencias. Las definiciones de procesos anteriores son casos degenerados; tales definiciones deberán incluir normalmente variables locales y declaraciones de procedimientos.

En Pascal Concurrente, las variables del sistema son tratadas como una forma especial de estructura de variables. Las definiciones anteriores son deJiniciones de tipos; ellas definen nuevos tipos de objetos del sistema Las variables actuales, llamadas " comportentes del sistema" son declaradas en la forma usual en el programa y son inicializadas en una declaración inicial en el hal del programa. A continuación se da el programa, donde los componentes del sistema se definen en definiciones de tipo, donde es posible declarar un

las compuertas. número de procesos similares entrance - control y control para controlar

Estas dehiciones necesitan ser refinadas para incluir unos parámetros adicionales para. identificar el proceso que controla cada compuerta, para que el proceso pueda comunicarse correctamente.

type { define tipos de sistema 1

procedure entxy arrive; procedure enw depart;

space - control = monitor;

begin end; { space control entrance control = process(tal1y:space control; me : integer);

tally.arrive; { llamada a un procedimiento del monitor) en& { entrance - control) exit control = process(tal1y : space - control; me : integr);

- -

al& { exit control ) var { declaración de componentes del sistema 1

wayinl, waym2 : entrance control; wayoutl, wayout2 : exit control;

-

counter : space-control; -

-

Page 111: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

begin { inicialización de componentes 1 irlit counter, wayml(Counter, 1); waym2(countery 2); wayoutl(counter, I); wayout2(counterY 2);

end.

Este ejemplo demuestra d m 0 los monitores pueden proveer coordinación donde sólo la exclusión mutua es rexprida Esta es implementada para el acceso al mon!itor. Si varios proasos intentar accesar el space control simultáneamente, algunos tendrán que esperar para asegurar que los procesos se ejecuten secuencialmente. Pascal Concurrente emplea una cola first in first out) para l a entrada al monitor.

-

Debemos ahora introducir la idea tie una codicidn invariante, I, que debe ser establecida en la sección de inicidización de los monitores, para nuestro ejemplo, esta condición seria:

(spaces >= O) and ( space; <= max-spaces)

es decir, ningún proceso deberá dejar el monitor con un número negativo de espacios disponibles ó con más espacios que los dwponibles, que actualmente existan. Esta invariante es establecida por la inicialización de spaces, es un ejemplo sencillo, ya que el monitor incluye sólo una variable. Normalmente interrelaciona una colección de variables.

En Pascal Concurrente, la sincrctnización se lleva a cabo mediante un nuevo tipo de variable, la cola. Colas (Queues), pueden ser declaradas sdamente como variables permanentes dentro de un monitor, es decir, como una variable giobal. Estas son manipuladas sólo por tres rutinas estándar definidas para l a operación de éstas: delay, continue y empty.

Page 112: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Dada ma variable cok (I, la llamada a

resulta en que el proceso que llamó queda suspendido hasta que otro proceso ejecute el procedimiento complematario

que resulta con que el proceso suspendido reanuda su operación. En práctica, 4 es usado para d.@ el nombre del pmceso suspendido en ell4 una llamada a dehyo en una pila no vacía provoca un error.

La fimcibn bodeana empfyo permite: a un proceso determinar el estado de la variable tipo pila Queue.

Variables tipo Queue pueden ser acc;esadas sólo dentro del monitor, en el cual están declaradas, a s í que un proceso que opera en una cola debe tener acceso exclusivo al monitor al tiempo de ejecucibn.

A s í , siguiendo con el ejemplo, si el estacionamiento no está lleno, entonces spaces es mayor que cero. Un procesa que estci esperando en una cola, deberá asumir que, cuando este regrese a su operación, la condición B se deberá cumplir en (adición con la invariarnte I, lo que expresamos:

Antes de ejecutar una operacibn continue, un proceso deberá establecer la condición asociada., pero no deberá asurnir que la condicih la tomará más tarde, entonces, el proceso que regresa a su operación puede inmediatamente invalidar la condicion, es decir,

I y B { indica €3 I

Esto es ilustrado ( e n nuestro ejemplo donde un proceso deberá regresar un espacio vado e indicar que el estacionamiento no está lleno, pero el espacio puede ser ocupado inmediatamente para M proceso que espera, a s í que el estacionamiento puede estar lleno otra vez.

Page 113: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

La siguiente estructura modificada del monitor carpark space control ilustra el uso de: colas (queues), para cuando el estacionamiento esté Üeno, el ejemplo asume que sólo hay un proceso entrance control. -

space - control == monitor; { permite ver cuando estacionamiento está lleno 1

const max spaces = 100;

V U -

SP- : O..mwc spaces; space ready : queue;;

- -

procedure entry arrive; begin

if spaces = O then

spaces := spaces - 1; delay(space r d y ) ; -

end; procedure errtry depart; begin

spaces := spaces + 1; t;ontinue(space - ready);

end; be;@

enld.

spaces := m a spaces; -

Page 114: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

El procedimiento arrive puede ser extendido para indicar a un cliente que está esperando que el estacionamiento está lleno:

procedure entry arrive; be€*

if spaces = O then begin

+dicate delay>;

<rescind delay>; delaY(SP=.-readY);

-

end; -

spaces := spaces - ‘1; end;

2.4. Ejemplo : B i l f .fer Circular .

El sedforo lock provee la exclusión mutua, es implementado automáticamente por el mecanismo de entrada del monitor. Los semáforos data - available y room available proveen la sincronizacih, mediante las colas correspondientes datu - reudy y room - reudy :

cyclic - buffer = monitor;

const max-buf= 100; bufkize = 101; { m;ur_buf+ 1 1

V U l m f : array[O..max buf] of object; next in, next out - - : O..max-buf; count : O..bufkize; data - ready, room-ready : queue;

-

Page 115: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

protdwe entry produce ( item : object); begin if count = bufsize then

delay(room ready); b a n e x t in] y= item; next in := (next in +l) mod bufiize; count := count + 1; continue(data - ready);

- - -

end;;

procedure entry consume(:var data : object) ; begm

i f count = O then

data := bu@mtt-oult]; next - out := (ne&ut + 1) mod bwfsize; count := count - 1; continue(room ready);

delay(data rerady);

end; -

blegin { inicializacih next - in :=O; next - out := O; count := o;

end; { cyclic buffer 1

La invariante del monitor es: next in = (next out + cuunt) mod bufSue; , es decir, el apuntador al último itm-del buffer. Esto se establece con la inicidizacibn : O = ( O + O ).

Una segunda invariante es requerida para el correcto hcionamiento del bizffer:

(#count >=O) and (muntt <= bukize ;

es de!cir, los datos no pueden ser exbxúdos antes de haberlos insertado. Estas condiciones form a usar las variables tipo colas (queue).

Page 116: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

La condicion asociada con room-retsdy es count < bufkize

Y data - rea& requiere que courlt o

2 5 Moní tores a n i d a d o s .

Es dificil la inltegración de anidamientos simples entre llamadas a diferentes monitores , debidamente integrada la lexclusibn mu- El siguate ejemplo ilustra el problema general. Teniendo una variable cola que puede m e r s610 un nombre de urn proceso, &a d usada para d e h r un monitor,fifo, para proveer una cokr múltiple de un arreglo de colas las cuales pueden ser usadas por otros monitores.

comt max-es = 5;

type fi.fo = monitor;

bufq : array[O. .max+es] of queue; last in, last out, waiting : O..max_gates;

procedure e&y fdelay; begin

Val.

waiting := waiting + 1; last-in := (last-in + 1) mod (max_gates + 1); delay(bufq[last-in]);

end; procedure en9 fwntinue; begin

i f waiting > O then begin

waiting := waiting - 1; continue(l,uf4[last-out]); last-out :== (last-out + 1) mod ( rnax_gates t. 1);

{ continue debe ser la última sentencia que fuena a salir 1 end;

end;

Page 117: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

begin waiting := o; last in :=o; last out := o;

-

end; cfifo )

space - control = monutor(fqueue : fifo);

spaces : o..maIx - spaces; VW

procedure entry arrive;

if spaces = O then begin

fqueue.fdelay; { espera en fXo 1 spaces := spaces - I ;

end; procedure enm depart; begin

spaces := spaces1 + I ; fqueue. fC0ntinu.e;

end;

spaces := max spaces; begm

end; { space_tmtrol 3 -

3. c S P.

3 . 1 Introducción.

El Communicating Sequential Processes (CSP) es un lenguaje marco para la programación concurrente, acontseJab1e en un entorno de red de microordenadores con almacenamiento distribuido. Los sigwentes conceptos son bhicos en este lenguaje:.

- Un programa en CSP consta de un número fijo de procesos secuenciales mutuamente disjuntos en sus espacios de direccionamiento.

Page 118: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

- La comunicación y sincronización se realizan por medio de mecanismos de e n t r a d a y salida.

- .Las estructuras de control secuencial se basan en los comandos protegidos de Dijkstra

La comunicac:ión en CSP se produce cuando un proceso nombra a un segundo como tiestino de su salida y el segundo proceso nombra al primero como &tente de su entrada ( la operación de salida puede verse como una send y la opleración de entrada como una receive). Los valores de salida se copian desde! el primer proceso al segundo ( el mensaje se envía y se recibe). Los mertsajes tienen tipo. Los tipos de los mensajes de salida y de los mensajes de entrarfa tienen que con:esponderse para que tenga lugar la comunicación. 12 transferencia de información se produce solamente cuando ambos procesos, emisor y lreceptor o destinatario, han invocado los comandos de salida y mtrad~arespectivamente. Así pues, tanto el proceso emisor como el destinatario pueden quedar suspendidos hasta que el otro proct=so este preparado para la correspondiente enW o salida. (Esto es, un esquema de comunicación de capacidad O). El dispositivo de E/S sirve tanto como mecanismo de comunicación como de herramienta de sincronización.

La notacibn sintáctica de los programas en CSP es extremadamente concisa y en consecuencia poco convencional. Aunque podriamos cambiar la notación para hacerla más convencional, hemos preferido la sintaxis realmente utilizada por Hoare.

3.2 Procesos productor y consumidor,

Para ilustrar estos conceptos, consideremos dos procesos, productor y consumidor, que quieren intercambiar mensajes. El comando de salida en productor tiene Ila forma:

consumidor!m (significa: send m al consumidor).

El comando de entrada en consumidor tiene la forma:

productor?n (significa: receive n del productor).

Page 119: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

La comunicación entre estos dos procesos se produce cuando ambos invocan los comandos de W S definidos arriba El efecto es equivalente a la asignación:

n := m;

En el ejemplo anterior, si el tipo asociado con la variable m no se corresponde con el tipo de n, la comlunicación no puede realizarse y ambos procesos esperaran (indefinidamente). Además, si uno de los procesos que comunica termina., la invocación subsecuente de una operación de mensaje por el otro proceso se resolverá en su terminación anormal.

En C S . , el ccmtrol secuencial se d i m mediante el uso de la notación de comandos protegidos de DijkstIra Un comando protegido tiene la fomra:

<protección> -> <listrz de comandos>

Una proteccj.ón consiste en una. lista de declaraciones, expresiones booleanas y un comando de entrada (todos opcionales). La protección falla si cualquiera de las expresiones booleanas tiene el valor falso o si el proceso nombrado en s u comando de entradal ha termínado. Si hay un fallo en la protección, el proceso en el que esta definida esa instrucción aborta. Si no hay fallo, se ejecuta la lista de comandos. Esta acción tiene lugar solamente después de que la acción del comando de entrada (si está) haya sido completada,

Los comandos protegidos pueden combinarse en un comando alternativo que tenga la forma:

[Gl -> C1 O G2 -> C2 O ... c1 On -S Cn]

Un comando alternativo especifica la ejecución de uno de sus comandos protqgidos integrantes. Por lo tanto, si hay fallo en todas las protecciones, lo hay en el comando alternativo y el proceso aborta. Si puede ejecutarse satisfactoriamente más de un comando protegido, se selecciona arbi trhente uno de ellos para su ejecución.

Page 120: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Los comandm alternativos puedan ejecutarse tantas veces como sea posible mediante el empleo de un comando repetitivo de la forma:

El comando alternativo se ejecuta repetidamente mientras no haya fallo. Cuando hay fall'o en todas sus protecciones, también lo hay en comando alternativo y el comando repetitivo termina El control se transfiere a la sentencia siguiente. Este esquema puede ilustrarse mejor por medio de un ejemplo.

3.3 Ejemplo : Problema d e l productor- consumidor con un b ú f f e r limitado.

Supongamos que queremos escribir un programa en CSP para implementar el problema dell productorkonsumidor con un buffer limitado de diez elementos. Los diez buffm tienen que ser encapsulados en un proceso CSP bounded-buffer definido se@:

bufk: (0..9) item; in, out: integer; in := o; out ::= o; *[in out + IO; producer ? buffer@ mod IO);

-:> in :=in+ 1; I out in; consumer ? more()

-'S consumer ! buffkr(out mod IO);

I out := out + I ;

El proceso productor emite un item p al proceso bounded-buffer ejecutando:

bounded-buffer !p;

Al proceso cmxwm.idor le entra un item q procedente del proceso bounded-buffer ejecutando:

bounded-buffer ! more(); bounded-buffer ? g;

Page 121: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

La asimetría entre la manera en que los procesos productor y consumidor invocan a bounded-baer se debe al requerimiento de que sólamente pueden aparecer comandos de entrada en las protecciones.

4. A D A.

4 . 1 . E l l e n g u a j e d e p r o g r a m a c i ó n c o n c u r r e n t e p a r a l a década d e 1980.

La mayor parte de los lenguajes des fueron drseñados para la escritura de programas secuencides. No proporcionan las características necesarias para escribir programas concurrentes.

AD. permite a un usuario individual establecer varias trayectorias separadas de control que operen en su beneficio. Esto se denomina mdtitarea

4 . 2 . M b t i v a c i o n e s p a r a l a m u l t i t a r e a en ADA.

Los mandos militares y los sistemas de control, a menudo, requieren supervisar varias actividades concurrentes. El mantenimiento de un reptro del estado de las naves de la marina del mundo entero, el control del tráfico abreo y la vigilancia aérea para prevenir la presencia de proyectiles enemigos son ejemplos de sistemas qpe deben supervisar varias actividades concurrentes, y responder rápidamente a cambios imprevistos en las operaciones de control. La escritura de software efkctivo para los componentes de: estos sistemas se filcilita en gran medida con el uso de un lenguaje de programación concurrente. Por esta razón, el gobierno de E. U. patrocin6 el desarrollo de ADA.

Los programas concurrentes, en general, son más dificiles de escribir, depurar y comprobar su correccibn que los programas secuenciales. Pero en muchas situaciones son mucho más fáciles de desarrollar, debido a que pueden expresar en forma m& natural las relaciones mherentes a los sistemas altamarte paralelos que se están modelando.

Page 122: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Se dice que: un programa es correcto si cumple con su especificación; es decir, si realiza lab que se supone que debe realizar. Antes los r&dores e s t a b I e c í a n la corrección de sus programas por medio de pruebas exhaustivas. Pero la corrección ha tomado una nueva dimensión en los últimos años, a saber, la noción de que un programa sea correcto en un sentido matemtitkc). Los investigadores del campo de la ingeniería de software han centrado su atención en el problema de saber cómo demostrar que un programa (=S correcto; e s t a b l e c e r la corrección de un programa con.currente es, en general, mucho más dificil que el caso de un programa secuencial. Los diseiiadores de ADA se interesaron por el desarrollo de m lenguaje que pudiera facilitar la demostracibn de la corrección de programas concurrentes.

AD. es un lenguaje de prograrnacibn de alto nivel, patrocinado por el Departamento de Defensa de E. U. y diseñado bajo el liderazgo de Jean Ichbiah. El lenguaje puede para la programación convencional, a s í como para requerimientos tt'rmicos especiales, como controlar o monitorizar varios dispositivos en tiempo real. Trataremos aquellos mecanismos del lenguaje cuyo propOsito es ofiecer un método para la escritura de programas concurrentes. El concepto de tarea, básico en este método, es un módulo de programa que se ejecuta asíncronamente ( una tarea puede verse como un proceso secuencial).

4.3. E l e n c u e n t r o ADA.

Los diseñadores de ADA decidieron mcorporar una témica llamada encuentro, apliau la exclusión mutua y la sincronización de tareas.

Exactamente dos tareas pueden mcorxtnuse a la vez en ADA: un llamador y un servidor. El llamador invoca una entrada del servidor. El servidor, cuando esta listo, emite una proposición accept para recibir la llamada. Si el llamador invoca. una entrada para la cual el servidor a h no ha emitido una aceptación, entonces debe esperar hasta la emisión de éstas. Si el servidor emite una aceptación para una entrada que aún no ha sido llamada, entonces el servidor espera (en aceptación) hasta que el llamador invoca la entrada

Page 123: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Cuando ha sido aceptada una llamada, ocurre el encuentro. El llamador pasa datos al servidor por medio de los parhetros de la llamada de la entrada Los datos son procesados por l a s proposiciones del cuerpo de la proposición de aceptación. Los resultados, si los hay, son pasados de regreso al llamadlor a travh de los pariunetros de entrada

El llamador espe:ra mientras el servidolr es ejecutado dentro de la proposición de aceptación. Cuando acaba el procesamiento, los parámetros pasan de regreso al llamador, el encuentro tmnina, y tanto el llamador como el servidor reanudan su operacion independrate.

Un aspecto interesante del encuentro ADA es que el llamador debe conocer la existencia del servidor y de las varias entradas del servidor. Pero este último acepta llamadas8 de cualquier llamador. Muchos llamadores puedlen intentar llamar a un sólo servidor. En este sentido, el encuentro es asirnétrico.

La exclusión 1nutu.a es garantizada :por medro de mecanismos básicos del sistema; solamante un llamador a la vez puede tener un encuentro con el servidor. Otros llamadores que intenten un encuentro simultáneo permanecen en espera. La s.incronización de tareas durante el encuentro es implícita. Después de un encuentro, los llanmdores que se encuentren en espera son procesados lpor medio de la disiciplina del primero-en-llegar, primero- en-ser-servido.

Las tareas pueden comunicar y sincronizar sus acciones mediante:

La sentenciat accept, que es una combinacibn de llamadas a procedimientos y transferencias de mensaje.

La sentencia select, que es una ~estructu.ra de control no determinista basada en el mecanismo de comandos protegidos de Dijkstra.

Veamos brevemente estas dos sentencias del lenguaje.

La sentencia wcept es básica para la comunicación y tiene la siguiente forma. (Los corchetes [I denotan una parte opcional, al tiempo que l a s llaves { 1 denotan una repetición de O o más veces).

Page 124: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

;accept<nombre de entrada>[<lista de parhetros formales>] [ do<instrucciones>end; J

Las instrucciones de una sentencia accept sólo pueden ejecutarse si otra tarea invoca el nombre de entrada. Invocar un nombre de entrada es sintácticamente lo mismo que una llamada a un procedimiento. Aqui tambih se pasan parámetros. Una vez que se ha alcanzado la sentencia end, pueden dievolverse parámetros y ambas tareas quedan libres para continuar. Tanta la tarea que llama como la tarea llamada pueden quedar bloqueadas hasta que la otra tarea est& lista con su comunicación correspondiente. A s í , sirve tanto como mecanismo de comunicación como de herramienta dle sincronización.

La elección entre varias llamadas tie entrada se realiza por medio de la sentencia select, basada en el concepto de comando protepdo de Dijkstra Por razones de lbrevedad describimos una forma restringida de la sentencia select, sin las sentencias delay y terminate. La sentencia select tiene la forma:

select [when <boolean-expression>* -> J

<acqt-statemenP [<statement*]

<accept-statement>) stateme men^] [else stateme men^]

(or [when <boolean-expressions> -> ]

end select;

La ejecución de una sentencia select tiene lugar como sigue:

1. Se evalúan todas las expresiones booleanas que aparecen en la sentencia select Cada sentencia accept cuya correspondiente expresión booleana sea evaluada como cierta, se etiqueta corno open (abierta). Una sentencia accept no precedida por una cláusula when siempre se etiqueta como open.

Page 125: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

2. Sólo puede seleccionarse para ejecución una sentencia accept abierta si otra tarea ha invocado una entrada correspondiente a esa sentencia accept. Si hay varias sentencias abiertas que pueden ser seleccionadas, se escogera una arbitrariamente para ejecución. Si. no puede seleccionarse ninguna y hay una parte else, s,e ejecuta &a. Si no hay else, la tarea espera hasta que pueda seleccionarse una sentencia abierta..

3. Si no hay ninguna sentencia accept abierta y hay una parte else, se ejecuta la else. ]En caso contrario se provoca una condición de excepcion. Error de selecciOn.

La sentencia accept dota a una tarea con un mecanismo de espera a un suceso determinado en otra tarea Por otra parte, la sentencia select dota a una tarea con u n 1 mecanismo de esperar a un conjunto de sucesos cuyo orden no puede predecirse.

Estos conceptos pueden ilustrarse con el problema del productor/consumidor con limitación tie bd€ers:

task body bounded-buffer is buffer: array[O. .9] of item; in, out : integer; count : integer; in := o; out := o; count := o;

begin loop

select when count < 10 -> accept insert(it:item)

in:=k+ 1; count :== count + I ;

or when count > O -> accept remove(it:out item)

do buffer[in mod 101 := it end;

do it := buffer[out mod 101 end;

Page 126: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

out := out + 1; count :== count - 1;

end select; end; end.

La tarea productora sitha un item p en bounded-bufEer ejecutando:

bounded-,buffer.insert(p);

La tarea comlumidora obtiene un item g de la tarea bounded-buffer BB ejecutando:

bounded-,buffer.remove(g);

En contraste con el CSP, tenemos una completa simetría entre l a s tareas productora y consumidora.

A continwcitjn se dan ejemplos donde se utilizan las sentencias, por separado y juntas.

4.4. Proposición Accept.

Se muestra una tarea ADA, CON'ROLADORDERECURSOS, drseiiada para controlar e:l acceso a un recurso simple compartido. La tarea permanece indefinidamente en un ciclo altemartte aceptando llamadas a l a s entradas OBTENERCOI\?TROL y ABANDON.ARCONTR0L.

task Controladorderecursos is entry Ob&mercontrol; enw Abandonarcontrol;

end Contraladorderecursos; task body Controladorderecursos is

begin loop accept Obtenercontrol; accept Abandonarcontrol;

end loop; end Contratladorderecursos;

Page 127: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Controladorderecursos. Obtenercontrol;

--usa e:l recurso

Controlado.rderecursos.Abandonarcontro1;

Las tareas cooperan de forma voluntaria en su uso de Controladorderecursos para asegurar la exclusión mutua Si varias tareas llaman a Obtenercontrol simultáneamente, sólo una será aceptada y las otras llamadas dleberán esperar en una cola.

Esto es en eslencia lo mismo que urn mecanismo de semt%oro binario. Si una tarea ignora el protocolo de co0pc:ración o lo usa mal, entonces no puede garantízame la exclusión mutua. Plor ejemplo, una tarea maliciosa que desea usurpar el control del recurso puede hacerlo emitiendo.

. . . Controladorderecmos. Obtenercxmtrol

y la tarea PO&. tener acceso al recwso (siempre y cuando no haya otra tarea en espera de Obtenercontrol).

4 . 5 . E - j e ~ p l o ADA: r e ; ! a c i c j n p r o d u c t o r / c o n s u m i d o r versión dos.

Considkrese z m a tarea productora que deposita una imagen de tarjeta de 80 caracteres en un buffer, y una tarea consumidora que saca los caracteres del buffer uno a la vez hasta que el b e e r queda vacío. El productor no puede depositar la siguiente línea hasta que el consumidor haya procesado la tot:didad de los 80 caracteres de la línea; el consumidor no puede comeflzar a sacar caracteres del b e e r hasta haber depositado una línea También, después que el consumidor procesa todos los caracteres de una línea, debe esperar a que el productor deposite la siguiente línea De otra manera, el. consumidor procesruía la misma línea más de una vez. Se muestra a continuación una tarea para sincronizar las tareas productora y consumidora

Page 128: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Tarea para la sincronización de una tarea productordconsumidora.

task Convierteimagendetaqeta is type Imagen,tqeta is array[ l.. 801 of CHARACTER, entry Depositatarjetflarjeta: in Innagentarjeta); entry Leecas-acter(Siguientecaractc:r: out CHARACTER);

end; task body Ccnwkrteimagentaqeta is

Bufferdetarjeta : Imagentaqetrl; h e w

loop accept Dlepositatarjeta(Tarjetx in Imagentqeta) do

end Depositatarjeta; for Posicim in l . .80 loop accept Lleecaracter(SiguientecntecElracter : out CHARACTER) do

end Leecxuacter; end loop;

Bufferdetqeta := Tarjeta;

Siguienteearacter := Bufferdetqeta(Posicion);

end loop; end;

Tareas productora y consumidora:

task Productor; task body Productor is

use Corrvierteimagendetarjeta; Nuevatarjeta : Imagentqeta;

begin loop - - crea NuevatarJeta; Deposit&arJeta(Nuevataxjeta);

end loop; end; task Consumidor; task body Consumidor is use Convierteimagendetaqeta; Nuevoauacter : CHARACTER

Page 129: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

begin loop Leeccllracter(Nuevocaracter)caracter);; procesa Nuevocaracter;

endloop; end;

4 . 6. La proposicidn Select . Las llamadas de entrada no necesariamente deben ser aceptadas de un

modo rígido y preespdcado. AD-4 proporciona la proposici6n select para hacer que las Weas acepten las llamadas de entrada de un modo m& flexible. Una forma común de la propcrsición de selección es:

select when Condicionl=) accept Entradal

secuencia de proposiciones;, or when Condicion2 + accept or ... else

secuencia de proposiciones; end select;

A veces se concede una cantidad: fija razonable de hacenamiento temporal para ]:as comunicaciones a. través del buffer entre procesos consumidor y productor. Esto puede ser simulado por un arreglo del tamaÍío designado. El productor deposita datos en los elementos sucesivos del anreglo. El consumidor :los quita en el orden en que fueron depositados. El ]productor puede ir varios pasos delante del consumidor. El productor llenara el último elemento del arreglo. Cuando produce más &os, tiene que regresar y comenzar ab depositar de nuevo datos en el primer elemento del tmeglo (suponiendo, desde luego, que el consumidor haya retirado los datos previamente colocados allí por el productor). De esta forma, el arregllo se cierra en círculo; de aquí el término de buffer circular.

Page 130: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Se muestra una implementación ADA de un buffer circular. La proposicih de selección permite a la tarea dar servicio a las llamadas a entradas apropiadas. El guarda (una condición que sigue a l when) Bufferenuso < Buffers permite que sea aceptada una llamada a Escrimaquett: siempre que haya espacio disponible. El guarda Bufferenuso > O permite aceptar una llamada a Leerpaquete siempre que el buffer contenga datos.

task Buffercircular is type Paqut:tedatos is array( l . . 80) of CHARACTER, entry Leepaquete(Paqu&e: out Paquetedatos); entry Escriiturapaquete(Paquete: in Paquetedatos);

end; task body I 3 ~ a c i r c d a r is

Buffers : constant INTEGER :== 20; Anillo : amy( 1 ..Buffers) of Paquetedatos; Buf€ermuso : INTEGER range O..Buffers := O; Proximodentro, Proximofuera : INTEGER range l. .Buffers := 1 ;

begin loop select when Bufferenuso Buffers ==>

accept Escriturapaquete(Pac1uete: in Paquetedatos) do Anillo(Proximodentro) := Paquete; end; Buff:renuso := Bufferenuso + 1; Proxiimodentro := Proximodentro mod Buffers + 1 ;

accept Leepaquete(Paquete: out Paquetedatos) do Paquete := Anillo(Síguieni:efuaa); end;

Bufferenuso := Bufferenuso - 1; Proximofúera := Proximofbera mod Buffers + 1;

or when Buffersenuso > O =>

end select; end loop;

end;

Page 131: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

4.8. Ejemplo ADA: Lectores y Escritores.

task Escritoresyktores is procedure Istor(Valor1ector: out XNTEGER); procedure lEscritor(Valorescritor : in INTEGER);

end;

task body EscritoresyLectores is VariableccBmpartida : INTEGER; Lectores : INTEGER := O; entry Comienzalectura; e n q Lectl~erminada;

procedure :Lector(Valorlector : out INTEGER) is begin Comidectura; Valorlectcm := Variablecompartida; Lecturateminada; end; begin

accept EscritolfValorescritor : in RVTEGER) do

end; loop

Variablecompartida := Valorescritor;

select accept comienzalectura; Lectores := Lectores + 1 ; or

accept Lecturatt73-minada; Lectores := Lectores - 1 ;

when Lectores = O => acce:pt Escritor(VaIorescritor: in INTEGER) do Variablecompartida := Valorescritor;

end; end select;

end loop;

or

end;

Page 132: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

En esta primera S O ~ ~ Ó I I , an Escritor debe escribir a Variablecompartida antes de que cualquier Lector pueda acceder a ella. ~ s t o asegura la definición del valor de Variable compartida antes de la primera IeChUa

Despub de t z c a b a r el primer Escritor, la tarea entrará en un ciclo indefinido. Si n.o hay ningún Escritor activo, entonces puede iniciasse cualquier niunercb adicional de Lectores. Esto, por supuesto, puede resultar en un aplazamiento indefinido de Lmtores. El siguiente Escritor puede ser iniciado sólo cumdo no hay Lectores activos, pero aún si hay un Escritor en espera, la seleccibn aleatoria inherente a la operación de selección puede permitir a un Lector en espera proseguir primero. Esta solucih aplica la exclusión mutua, pero los procesos pueden ser postergados indehdamente. Obsérvese que Lector es un procedmiento, más que una entrada. Esto permite leer a la vez varias tareas.

4 0 9. Versión dos. Lectores y Escritores.

task LectoresyEscritores is produre Lector(Valor1ector : out lNTI3GER); entry EscritoxfVdorescritor : in INTEGER);

end;

task body LectoresyEscritores is Variablecompmtida : INTEGER, Lectores : INTlEGER := O; entry ComimdecturK

procedure LeCttor(Valor1ector: out INTEGER) is begin

entry Lecturatermina&a;

C o m i d e c m Valorlectura T= Variablecompartida; Lecturaterminada, end;

begin accept EscritorfValorescritor: in N'EGER) do

end; Variablecompartida := Valorescritalr;

Page 133: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

loop select

when Escritoicount = O =S

Lectores := Lectores + 1; accept: comienzalectura;

or accept I,ecturatemrinada,

LectoIes := Lectores - 1 ;

when :Lectores = O => acceplt Escritor(Valorescritor: in INTEGER) do Variablecompartida := Valcmscritur~ end;

loop select

or

accept Comienzalecturq Lectores := Lectores + 1;

else exit;;

end sdect; end loop;

end select; end loop;

end;

La versión dos también obliga a Escritor a escribir una vez antes de que pueda proseguir cualquier Lector. Consideremos ahora el cicIo principal, e1 cual se repite indefinidamente.

El primer guardia prueba Escritor'count, para determinar si hay ai@ Escritor en espera. Si no lo hay, entonces puede iniciarse un nuevo Lector. De hecho, mientras no haya ningún E:scritor en espera, pueden iniciarse más Lectores.

Page 134: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

La segunda operación de aceptación del ciclo principal, accept Lectumtermin& no tiene ningún pudia, a s í es que se encuentra siempre abierta. De estal manera, cualquier Lector que haya terminado su lectura siempre será weptado, fdtando c a n esto la reducción de Lectores a cero, para que otro Emitor pueda ser iniciado.

Cuando el nlúmero de Lector es :lidmente reducido a cero y hay un Escritor en espera, este último es iniciado. Inmediatamente después de terminar este ESscritor, pueden proseguir todos los Lectores que se encuentran en aspera.

Cuando un Escritor está activo, el encuentro está siempre en efecto, a s í es que la exclusión mutua est& garantizada- La verdadera clave esta en como la versión dos maneja los Lectores.

Ningún Lector puede estar activo cuando lo está un Escritor, debido a que el encuentro garantiza la exclusih mutua Por tanto, consideremos Io que sucede cuando no hay ningún Escritor activo.

Si no hay ningún Escritor en espera, entonces los Lectores continuarán siendo iniciados. Tan pronto como un Escritor comienza su espera, entonces ya no podrán iniciarse nuevos Lectores. Todas las llamadas a Lecimaterminada serán rweptadas hasta que Lector quede reducido a cer'o. En este punto, el *&a Lectores = O es ajustado en verdadero y se acepta el primer Escritor en espera Cuando este Escritor termina su opexación, todos los :Lectores que han llegado desde el momento que 13scritor comenzó son iniciados en el ciclo interno.

Esta iniciacilón en masa se detendrá tan pronto como una iteración del ciclo ejecute accept Comienzalectura y no haya ningún Lector dispuesto. Esto causa la qlecución de la cláusula else, y la consiguiente salida del ciclo.

Aún hay una. debilidad en la versitjn dos. En e1 ciclo interno es posible que un Escritor en espera sea poste:rgado indefimdamente por un d u j o pid do de Lectclres. Siempre que los Lectores lleguen más rápido de lo que el ciclo puedrl aceptarlos, los Esmitores serán retrasados. Es posible desarrollar una solución mejor de LectoresyEscritores con ADA:

Page 135: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

5.MODUW-2.

5.1. Introduccicjn.

Generalmente:, distingwmos los siguientes tipos de sistemas:

La computadora consiste de varios procesos idénticos. El proceso programado es ejecutado en concurrencia genuina.

La computad.ora consiste de un útrim procesador. Este actúa sobre un hito proceso en cualquier instancia tie tiempo, y se intercambia para cada uno de los procesos a ejecutar. Los procesos se dice que son quusi- concurrentes.

5.2. Prucesus y currut inas.

A continuation dwcutiremos la formdacion de procesos y sus interacciones e n . tthninos de MODULA-2. Su implementmibn est& basada en computadoras con un solo procesador, sistema anterior, y el concepto de Corntinu; es dtxir, un sistema quasi-concurrente.

Para el uso tie procesos concurrentes introducimos el MóduloProceso. Este tiene las venta~as de la multiprogramacic5n de alto nivel de virtual abstracción sin necesidad de constructos adicionales al lenguaje. Esto provee l a s faciliidades de MODULA-I y más de Concurrent Pascal.

DEFINITIONl MODULE Proceso; TYPE SYGIVAL; PROCEDUIXE Startproceso(P : PI20C; n : INlXGER); (*empieza ~ r n proceso concurrate con programa P y espacio de

PROCEDUIW SEND(VAR s:SIGNAL); (* un proceso esperando por S ea resumido *)

PROCEDUIXE WAIT(VAR s:SIGNAL); (* espera por algún otro proceso para enviar S *)

PROCEDUIE Awaited(s:SIGNAL) : BOOLEAN; (* Awaited.(s): "al menos un proceso es esperado por S *)

PROCEDUIW Init(VAR S: SIGNAL,); (* iniciacitjn *) END Proceso.

trabajo de tamaifo n *)

Page 136: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Una llamada a Startproceso(P,n) empieza la ejecución de un proceso el cual se expresa por un procedimiento P. A s í &te proceso es ejecutado en genuina o quasi-concurrencia, claro que depende de la implementación del proceso usado. Cada proceso requiere un cierto espacio de trabajo en el almacenamiento1 para alojar sus variables locales. El tarnaiio del espacio de trabajo en términos de número de palabras, es n; este es elegido dependiendo del núniero de variatks locales usados por el proceso. (Un espacio típico es de 100 palabras).

La comunicación entre procesos ocurre en dos distintas formas, llamadas vía común, shared variables, y otr~t vía llamada signals. La primera también llamadta variables comunes, es usada para transferir datos entre procesos, y hacer armoniosa la cooperación entre ellos. Ningún proceso debe referentiar variables comunes mientras otro proceso está *

desmollando alguna acción crítica sobre éstas. Una solución razonable a este problema es el encapsulamiento de variables comunes en un módulo el cud garantice la exclusión mutua de procesos. Tal módulo es llamado un MONZTOR. Sig:nuls, exportado corno un tipo de datos desde el módulo Proceso, no 1le:va en si datos, pero sirve para sincronizar procesos. Sólo dos operaciones son aplicables a Sign&: un proceso puede enviar una señal y puede esperar por una señal (algún otro proceso enviándole). Cada señal denota una cirxta condición o estadio entre las variables del programa, y enviando la seilal puede implicar que esta condición ha sido enviada, Un proceso que espera por alguna sdial puede entonces asumir que esta condición ha sido introducida mientrm el proceso es resumido. El envio de una seiial reactiva al menos un proceso. (De otra forma uno de los procesos despertados debe rápidamente invalidar la condición, CELUsando que otro proceso proceda sin tener permiso:). Enviar una señal para aquellos procesos que nd3 están esperando es considerada como una operacicin nula

Page 137: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Otra regla importante de programllción es que las shred variables son declaradas y ocultadas sin monitores. Un monitor es un módulo el cual garantizala exclusión mutua de procesos y puede guardar laintegridad de los datos locales. El acceso a estos datos es - porque están ocultos - restringida a sentencias de los procedimientos del monitor y entonces el monitor garantiza que una llamadal a un proceso es temporalmente bloqueada mientras otro proceso está ejecutando alguno de los procedrmrentos del monitor, la exclusión mutua del acceso a datos es automáticamente activada Un mó8dulo es designado para ser monitor especificando una prioridad en s u cabecera El valor de prioridad es un número positivo.

5.3 . Ejemplu: Pruductores/Consumidores.

Enseguida se muestra un ejemplo, que ilustra lo anterior, que lleva a cabo el intercambio de datos entre varios procesos. Esto envuelve tipicamente, corno ya hemos visto, e:l uso de un búffix; asumimos que el proceso puede [depositar datos en ell búffer y sacar datos del búffer. El búffer es la principal shared variable; juntos con las operaciones Depositar y Sacar &a es encapsulada en un monitor. Los procesos tienen llamadas a Sacar y Depositar y son tipicamente cíclicas. Estas llamadas dan cuerpo a su interacción. Si un proceso mntiene llamadas a Depositar, es un Productor. Proc,esos con llamadas a Sacar son llamados Consumidores.

Asi tenemos el ejemplo de los ~ ~ o d ~ c t ~ r e s / C ~ ~ s u m i d o r e s ya tratado anteriormente.

El bliffer es declarado como u n 1 variable tipo arreglo usado en una manera circular. Dos condiciones de espera tenemos: Un productor llamando a De~positar puede enconbar el b ú f k lleno, o un Consumidor llamando a Sacar puede encontrarlo vacio. Estas dos condrciones dan paso a la declaración de dos signals llamadas novacio y nolleno usadas para retroactivar unit proceso que espera El monitor Bzífler es programado como un módulo local, y n es el número de datos depositados en el Búfler.

Page 138: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

MODULE BúfFer[ 11; EXPORT' Depositar, Sacar; IMPORT SIGNAL, SEND, WAIT, Init, Tipoelemento; CONST N = 128; (* tamaño de4 bmer *) VAR n : [O..N]; (* número de elementos depositados *) nolleno:-SIGNAL; (* n < N *:) novacio : SIGNAL; (* n > O *,) in, out : [O..N-l]; (* ínhces *:) buf: ARRAY[O..N-1] OF Tipoelemento;

PROCECKJRE Depositar(x:Tipoelemento); BEGIN IF n = Ni THEN WAIT(no1leno) END; (* n < Ni *) n := n+l; (* O < n < = N *) buflIin] :=x;

SEND(novaci0); in := (in+ 1) MOD N;

END Depositar; PROCEDURE Sacar(VAR x: Tipoelemento); BEGIN IF n = O ' T H E N WAIT(novaci0) END; (*n>O*) n:=n-1; (* O<=n<N *) x := baout]; out := (out + 1) MOD N; SEND(nollen0); END Sacar; BEGIN n := O; in := O; out := o; Init(no1leno); Init(nov,acio); END BúlTer

Page 139: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Esta versión del algoritmo tiene la propiedad de mandar una seiial cada vez cuando un elemento es depositado o sacado. Pero, en principio, una señal de sincranización necesita sólo ser enviada, si un cornpailero esta esperando. Este es un buen principio para minimizar el número de intercambios de señales y para reducir el grado de acoplamiento de procesos. Una jimplementación en ésa direwión se tiene con la versión del Barbero durmimte de Dijkstra. Este extiende el rango de valor de la variable n con los siguientes sigdicados: ( válido si ningún proceso ha entrado al monitor):

n < O : El bMer está vacío y -n consumidores estan esperando. O <= 11 <= N : n casillas del bmer están llenas, no hay procesos

N < n : El bmer está lleno y n-N procesos están esperando. esperando.

Los dos protxhniemtos son ahora declarados como:

PROCEDURE Depositar(x: Tipoelemento); BEGIN n:=n+ 1; IF n > NI THEN WAIT(mollen0);

END; (* n <= N *) bufCin] := x; in := (in+l) MOD N; IFn<=OTHEN

SEND(novaci0);

END Depositar;

PR0CECUR.E Sacar(vAR x : Tipoelemento); BEGIN n := n -1.; IF n < O THEN

EDID; (* n>=O*) x := burtl[out]; out := (out+l) MOD N;

WAI"(novacio);

Page 140: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

IFn>=NTHEN SEND(:nolIeno);

END END Sacar;

5.4. Carrutinas.

Ahora dirigimos nuestra atención en el problema de la implementación. de el módulo Proct?so y presentar una posible solución. Enfatizarnos que es sólo una entre muchas posibles. Está designada para una máquina con un sólo procesador a atender el proceso. La solución está basada en el concepto de Corrutimz. Una Corrutina es un programa secuencial esencialmente como un proceso, que luego drscutiremos. Las diferencias conceptuales entre procrwos y corrutinas pueden ser escritas como sigue:

a. Corrutirtas son conocidas para ser ejecutadas con quasi- concurrencia. :Pero su uso introduce la dificultad de la interacción con genuina concurrencia de procesos.

b. El procesrador es pasado de ma comtina a otra corrutina por una sentencia de transferencia explícita. La ejecución de el destino de corrutina resume desde el punto donde ésta fué suspendida por la última sentencia de transferencia

Es evidente que en una máquina con un sólo procesador un proceso puede ser implementado como una corrutina, el cual emerge de un concepto de bajo nivel. Esta proximidad a las actuales computadoras es evidenciada por la sentencia de transferencia correspondiente a un salto de control. Tal salto de corrutina de:be almacenar el estado actual de la corrutina actuajl, la cual va a ser suspcmdida, tal que ésta puede ser resumida cuando otra corrutina transfiera el control volviendo a la suspendrda En cada transferencia, el destino de la corrutina es identificado explícitamente, y sus contrastes con las sentencias W N T y SEND deben ser usadas para la sincronizaci0n de procesos.

Page 141: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Como en MC)DULA l a s corrutinas son consideradas como facilidades de bajo-nivel, sus tipos asociados y sus operadores tienen que ser importados desde el módulo SYSTEA4, o desde otro módulo de bajo nivel. Necesitan en prutticdar el tipo mDNCSS y el procedimiento T M S F E R . La cabecera del procedimiento TRANSFFA es declarada así:

PROCEDURE TRANSFER(VAR source, destination: ADDRESS)

Su invocación causa que source sea suspendido - en orden a ser resumido despds con la declaracith de la siguiente transferencia- y destination debe: ser resumido en el punto donde fire suspendido. El orden para crear una. corrutiw, se debt: invocar primero al procedimiento NEWPRQCEESS,

PROCEDURE NEWPROCESS(P:PROC; a:ADDRESS; n:NTEGER;VAR new :ADDRESS)

Donde P denota el parhetro procedimiento el cual constituye el programa para la nueva corrutina creada. a es la dirección original del espacio de trabajo necesitado para akm.cenar las variables locales de la comtimz y para almacenar los estados de la corrutimz mientras éSta está suspendida, n denota el tamaño de este espacio de trabajo en unidades de almacenamientat. La. llamada asigna a. la variable new ( una referencia a) la comtina creada cuyo estado es inicializado tal que, cuando el control es transferido a dista, la ejecución empieza al principio de P. Entonces, las cormtinas empiezan por una transferencia explícita; ellas deben ser terminadas por dicha transferencia.

Presentamos ahora una imple~nentación del módulo Proceso en términos de corntin=. El aspecto esencial es que l a s Ilmadas a WNT y SEND tienen que estar en términos de transferencias, en las cuales el destino debe estar identificado. Consecumtemente, el mbdulo Proceso debe guardar una arhinistración de procesos que distribuya el tiempo del procesador en con una estrategia imparcial entre los procesos. Esta administración es llamada un planificdor (scheduler). Normalmente, este es parte del sistema operativo de la computadora.

Page 142: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

IMPLEMm,I'ATION MODULE Proceso [ 11; FROM SYSTEM IMPORT ADDIESS, NEWPROCESS, TRANSFER, FORM Storage IMPORT ALLOC.ATE;

TYPE SIGNAL, = POINTER TO Ilescriptordeproceso; Desaiptordeproceso =

RECORD next : SIGNAL; (* ring *> queue : SIGNAL; (* cola de! procesos en espera *) cor : ADDRESS; ready : BOOLEAN; m;

VAR cp : SIGNAL,; (* proceso actual *)

PROCEDURE Empiezaproceso(P:PROC; n:CARDINAL);

BEGIN VAR s0:SZGNAL; wsp:ADDR€bSS;

so := cp; ALLOCATE(wsp,n); ALLOCATE(cp, SIzE(Descriptordeproceso)); WITH cp* DO next := sOA.next; sOA.next ::= cp; ready := ?'RUE; queue := NIL; END; NEWPROCESS(P, wsp, n, cpA.c:or); TRANSFESR(sOA.cor, cpA.cor);

END Empiezaproceso;

PROCEDUEZR SEND(VAR S : SEGNAL); VAR SO : SIGNAL;

BEGIN IF S # NIL 'lXEiN

WITH cpA DO S := queue; ready := TRUE;

so := cp; cp := S;

Page 143: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

queue := NIL; END; TRANSFIZR(sOA.cor, cp^.cor);

END END SEND;; PROCEDURE WAIT(VAR S :SIGlYAL); VAR SO, sl : SIGNAL;

BEGIN (* inserta cp en cola S *>I IF S = NIL ?'HEN

ELSE S := cp;

so := S;

sl := sOA.queue; WILE sl # NIL DO

END; SO := sl; :sl := sO*.queue;

sO*.queue := cp; EBD; so := cp;

REPEAT cp ;= cpA.neXt UNTIL cpA. ready; IF cp = SO THEN (* abrazo mortall *)

END; sOA.ready :=, FALSE; TRANSFEIZ(sOA. cor, cp". cur); END WAIT;

HALT

PROCEDURS Awaited(s:SIGNAL,) : BOOLEAN; BEGIN

END Awaited; RETURN !S # NIL

PROCEDURS Init(VAR S : SIGNAL,); BEGIN

S := NIL; END Init;

Page 144: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

BEGIN ALLOCATl3(cp, SEE(Descriptordeproceso)); WITH cp* DO next := cp; ready := T F L U E ; queue := NIL;

END

Cuando un proceso empieza con una llamada de Empiezuprucesu(P,n) , una descripción del proceso y un espacio para su currutinu asociada es almacenado. LA descripción es insertada en una lista circular conteniendo la ejecución actual del proceso. Por recorrido de la lista, cualquier proceso puede ser alcanzado. El proceso sucesor es denotado por el campo de descripción llamado next.

L a cuestión c:rucial es la representación de las seiiales (signals). Una señal, representa una condición de despe:rtar, esto representa al nivel de implementación el conjunto de procesos que están esperando por la señal. Entonces el número de estos procesos es desconocido, una sensible solución es organizar estos en una lista ligada. Entonces, una variable signal representa la cabeza de la lista, y cada descripción de proceso contiene un campo ligado al siguiente proceso es;perando por la misma señal. Su valor es NIL si no tiene procesos.

SEND() tomla el primer elemento de la lista S y transfiere el control desde el proceso que envía (identificado por cp), a ese proceso. WMT(s) agrega el proceso que llama (idenlificado por cp) al final de la lista s. Agregando al final de la lista, se puede controlar que proceso es el que sigue para tomar el control, ya que la lista representa una cola, primero en llegar? primera en salir. En princ;ipio, cualquier proceso que no este esperando, no puede ser reanudado. El otro descriptor adicional ready es usado para determinar rápidamente si un proceso está listo o no para su reanudación.

Page 145: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

( Esta solución tiene como caraaterística que al remover un proceso que espera de la lista requerirá su re inserción cuando vuelva a ser reactivado. Esta solución se prefiere cuando se asume que el numero de procesos es pequeiro).

En principio, ].a interacción de procesos debe ser confiada a un monitor; es decir, un módulo que garantice la exclusión mutua,

6. C++ Corrcurrente.

6.1 In t roducci Ón . La programwión orientada a objetos es un modelo de programación que

plantea la descomposición de sistamas en un conjunto de entidades distinguibles ll~amados objetos, los cuales poseen un estado o configuración inkma Es estado de un objeto se caracteriza por una colección de propiedades medible que le es propia El estado del objeto se puede trmsfc)rmar por la aplicacihn de ciertas operaciones, l a s cuales constituyen el único medio de interacción con el exterior.

La programación concurrente, corno ya se ha dicho, es otro modelo que permite tratar problemas que involucran múltiples entidades activas desarrollhdose con un paralelismo potencial. Las entidades activas o procesos poseen un comportarnientc~ propio que se manifiesta por la ejecución de cicxtas operaciones que les permite interactuar con otros procesos. Los procesos corresponden a nuestra idea usual de programas secuenciales.

En la programación concmente orientada a objetos, se unifican los conceptos de objjeto y proceso. Los objetos, vistos como una colección de atributos y opexaciones, se consicferan objetos pasivos, porque se manifiestan únicamente cuando reciben el control del procesador. Los procesos, vistas como entidades relativamente independientes, se consideran objetos activos porque cada uno posee el control del procesador ( propio o compautido con otros procesos). La programación concurrente orientada a objetos aprovecha las similitudes que guardan ambos paf-adrgmas y trata de resolvcx sus diferencias.

Page 146: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Los modelos de programación orientada a objetos y concurrente guardan ciertas similitudes ya que comparten la habilidad para manejar sistemas grandes y complejos: permiten el ocultamiento de la información, la estanhzación de herramientas, la clasificación clara entre datos propios, procedimientos e interfaces, la compilación separada de módulos y el aishmiento de las modrfiicaciones.

Existen sin embargo, algunas diferencias que se deben identtticar. La principal se refilere a la naturaleza pasiva o activa de l a s entidades que manejan ambos modelos. La programación orientada a objetos trata con entidades pasivas, es decir, aquellas que se mdestan cuando el procesador ejecuta alguna de las operaciones propias del objeto. Por otra parte, en la programación cont:urrente, las unidades bhsicas para la construcción de programas, los pralcesos, son entidades activas ya que poseen un flujo de control propio. Algunas consecuencias importantes de estas &ferencias son:

a. El modelo de objetos plantea que un programa se puede considerar como un escenario caractaizado por un sincronizador global que determina el concurso de los difkrentes objetos. Los objetos poseen propiedades e interfaces bien definidas que son usadas por el sincronizador para crearlos, destruirlos o relacionarlos. El sincronizador es el adminrstrador de los recursos que requieren los objetos (procesador, memoria, etc) y corresponde con c:l flujo del control del programa en ejecución en . u n ambiente de monoprogramación.

b. El modelo de procesos plantea un escenario distinto. No existe el concepto de u n . sincronizador global. Por esta razón, no se requiere de un conocimiento exhaustivo del sistema y de hecho, una suposición básica en este modelo es, precisamente, este no determinismo. La ausencia del sincronizador global tiene la ventaja de reducir la complejidad de cualquier sistema ya que se pueden diseñar objetos activos relativamente autónomos e indepenhentes de la aplicación. Sin embargo, el precio que se debe pagar po;r esta elevada modularidad es el degradamiento de la eficiencia en la ejecución. No obstante, habiendo reconocido la importancia de este problema, se le ha tratado de resolver al mismo nivel del hardware ya desde hace años.

Page 147: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Puesto que todo objeto pasivo pued.e considerarse como un objeto activo con actividad nuda, tenemos que conclluir que el concepto de proceso es el más general, y por esta d n , debemos adoptarlo como fundamental para afrontar la complejidad de los problems reales. En muchas ocasiones, los programas conau-rentes no sólo permiten construir un modelo de la realidad sino que, además, permiten interactuar con ella, en un ambiente formado por numerosas entidades autónomas operando a diferentes velocidades.

Esto da lugar a un no determinism0 inherente a los problemas reales que hacen impolsible determinar la secuencia de acciones que se deben tomar para simular €1 interacm con el exterior. Por esta razón, es imposible conservar el moldelo de objetos con un único sincronizador global (flujo de control).

6.2 E l disefío d e l l e n g u a j e C++ C o n c u r r e n t e .

El Ienguge <I++ Concurrente se ha &señado en base al modelo de proceso distribuido de Brinch Hansen. El modelo permite describir una gran variedad de cctnstrucciones como casos especiales: losprocedimientos, las corrutinas, las clases, los monitores, los procesos, los sedforos, los recipientes y las trayectorias.

Las características del modelo de programación del lenguaje C++ Concurrente son:

a Un programa consiste de objetos pasivos y de objetos activos. Todo objeto pasivo st: considera como un objeto activo con actividad nula E1 comportamientot de los objetos pasivos se reduce únicamente a la iniciación de las variables por su constructor. Los objetos pasivos son instancias de clases definidas normalmente en ell C++, y en adelante, les llamaremos simplemente objetos. Los objetos wtivos son instancias de las clases derivadas de Process, y en adelante,, les llamaremos procesos.

Page 148: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

b. Un programa concurrente consiste de varios procesos que esthn corriendo simujltbeamente y que pueden durar indefinidamente. Cada proceso posee sus propias variables locales y no requiere de variables comunes para comunicarse. La estructura de la especificación de un proceso es como sigue:

class nom’bre - clase: Process( variables privadas // estado interno del proceso hciones privadas /I funciones auxiliares public: funciones publicas // servicios que presta el proceso nombre:(parhetros) // consbructor de la clase 1;

La definicibn del comportamiento del proceso se debe indicar en la h c i b n constructora de la clase

nombre c1ase::nombre - clase(parkmetros) { variaGes locales // variables auxiliares estatutos // comportamiento 1

La dehicibn del comportamiento en la función constructora indicando, adennk, el tamaño de la pila

nombre clase: :nombre - clase(pshetros):Process(tamañoqila) { variablt:s locdes // variables auxiliares estatutcbs // comportamientc)

1

c. Un proceso puede solicitar los servicios que ofrece otro mdante llamadas a procedimientos aunque estos sólo puedan ejecutarse hasta que se cumplan ciertas condiciones. En tanto, el proceso solicitante se ve forzado a esperar. A estos proce&mientos l e s llamaremos ser”ios (extern2 request). La comunicación tiene lugar mediante el intercmhio de dormrtcicjn entre los procesos usando los parhetros del procedimiento. De esta forma, los datos enviados al prestador del servicio se pasan por valor y los resultados que obtiene el solicitante del servicio se reciben por referencia:

Page 149: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

nombre clase: :servicio(parámetros) { variaGi& locales // variables auxiliares estatutos // comportamiento 1

en donde, pámetros indica los parárnetros pasados por vdor o por

Los servicios; que ofrece un proceso no pueden comenzar hasta que no se referencia,

hayan iniciado llas variables propias.

d. Los procesos se sincronizan por medio de mecanismos de varios niveles de abstracción. En el nivel más bajo, los procesos se sincronizan mediante operaciones especiales como la suspensión del proceso en ejecución o las l l a m a d a s a corntinas. Err el síguíente nivel, la sincronización se realiza mediante estatutos no deterministicos Ilamados guardias. En el nivel mits ahto, se establece la sincronizacibn por 10s servicios que prestan los procesos: el cliente debe esperar a que el prestador pueda otorgarlo.

d. 1. Operaciones básicas de sincro~.lización:

d.2. Estatuto de sincronizacibn select

select when (condición) estatutos

6 bien

select{ when (condicion- I) estatutos- 1 ...

when (condicion-N) estatutos-N;

Page 150: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

d.3. Funciones publicas que ofi-ece un proceso.

proceso.s;ervicio (parámetros ar:tuaIes);

o bien proceso-:wxvicio)parámetros mtuales);

ya sea que un :proceso sea una variable (referencia) o un apuntador.

La operacion suspendt) causa que el proceso en ejecución ceda indirectamente el control a otro. El proceso suspendrdo se forma al final de una lista de procesos elegibles reatdyQueue para recibir el control del procesador. La elección del siguiente a ejecutarse la determina el admuristrador de procesos basado1 en la política round-robin. Por otra parte, la operacion trcm.@?rC.) cede directamente el control a otro proceso sin recurrir al admmstrador. La transferencia del control no se realiza si el proceso que lo recibe ya hubiera terminado su actividad.

El estatuto de sincronización select es una región protegida por guardias que seleccionat una serie de accjo~nes de entre varias posibles. Cuando se verifica alguna de las condrciones que vigilan los guardas con las cláusulas when, se ejecutan de inmediato los estatutos que le siguen. Cuando se verifica más de: una con&ción, se elige una de ellas al azar y se ejecutan los estatutos que le corresponden. Cuando no se verifica ninguna de las condciones, e:l proceso que ejecuta el estatuto select se ve forzado a esperar. Eventualmente, cuando alguna de las condrciones se verifica, la espera del proceso termina.

Una consec;uencia inmediata de la sincronizacih es que se garantiza la comunicación entre procesos, ya que una vez lograda, puede tener lugar la transferencia de mformaci6n. Ein este modelo, el intercambio de información se realiza mediante ulna comunicación síncrona bidirecciond. En la comwnicalción síncrona bidirecciond, el emisor de un mensaje (proceso solicitante de un servicio) debe esperar a que el receptor (prestador del servicio) se encuentre en condicionas de aceptarlo, y a recibir más tarde una respuesta, Cuando el receptor eventualmente recibe el mensaje, rediza las actividades necesarias para contestarlo, enviando el resultado al emisor. Finalmente, el emisor continua s u tra.bajo al obtener la respuesta.

Page 151: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

6.3 C a r a c t e r í s t i c a s d e l l e n g u a j e C++ C o n c u r r e n t e .

Las caracteristicas más relevantes del modelo en el que se basa el lengwaJe C++ Concwente se enumeran a conhnuación:

l . Abstracción de datos mediante clases ( C++).

2. Creación y destrucción estática y dinámica de procesos y corntinas (extensión).

3. Topología estática y d i n h c a de procesos (extensión).

4. Programación en el estilo de Proceso Distribuido (extensih).

5. Ejecución no deterministica de pIogramas (extensión).

6. Comunicación síncrona bidirectional (consecuencia del modelo).

7. Comunicación por canales ( extensión).

8. Compilacih separada de mótdulos y facilidades de depuración (ambiente).

9. Caracterización del sistema opmttivo como un proceso prestador de servicios.

6 . 4 E j e m p l o s :

A continuacih se presentan algunos problemas de concurrencia y su solución usando el lenguaje C++ Cortcurrente. La mayoría de ellos fueron tomados directamente del artículo de Winch Hansen.

Page 152: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Un semáforo consiste de un contador cntr, de una cola de procesos queue y de dos operaciones que lo accesan .wait0 y signal(). Cuando el contador es un número negativo, el proceso que: emite la operacibn wait0 se bloquea hasta que el contador sea cero o un número positivo. La operación signat() incrementa al contador rehabilitando e1 proceso suspendido por wait().

class Semaphore:Process { Queue quleue; int cntr; public: Semaphore(int); void wait(void); void signai(void); 1; Semaphore::Semaphore(int n) : PIocess (O) { if (n )= O) cntr = n;

1

if C--cntr O j suspend(queue, readyQueue);

1 void Semap!hore::signal(void) { if (cntr++ e O)

1

void Semaphore: : waiqvoid) {

readyQueue. add(queue. sub());

La llamada suspendqueue, re(adyQueue) que aparece en wait() establece que el proceso en ejecucibn será formado en queue y que el sigwente sera olbtenido de la cola de canhdatos readsueus. Por otra parte, en la llamada ~eryread~,add(queue.subI)) que aparece en signalu, extrae al proceso que primero haya. lIegado a queue, y después lo hace elegible para recibir el control inse~rtándolo en readyeueue,

Page 153: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Se puede form.ular una versión equivalente usando regiones protegidas como lo sugiere Brinch Hansen. Las regiones protegidas sdo pueden usme en la dehción (de I t s firnciones públicas de un proceso de modo que en esta versión, la clase! Semaphore debe aspecificme corno un proceso, aunque "no haga nada"' despub de redizar la iniciación. De hecho, el proceso se destruye lo G U . ~ no tiene ningún efecto sobre los procesos que usan las operaciones, debido a que la actividad del proceso servidor no incluye la administración del semhforo.

class Semaphore: Process { int m@; public: Semaphore(int init); void wait(:void); void signad(void); 1;

Semaphore: :Semaphore(int init): Process(0) { if(i& >=: 0)

cntr = intit; ( sigue ...) ( continúa ) 1

void Semaphore waít(void) { select when(cn1tr > O) cntr--;

1

void Semaphore signal(void) { cntr+-f-; 1

Page 154: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Los procesos que usen estas operaciones deben hacerlo así:

Semaphore S( 1); s.wait(); ... // Region critica

s. signal();

lo que ilustra una soluciún al problema de la exclusión mutua usando semáhros. El proceso semáforo es un caso tipico de un prestador de servicios: su actividad se reduce a estBb1ecer los valores iniciales de l a s variables. En adelante, sblamente atiende l a s solicitudes wait() y signa20 de otros procesos.

6.4.2. Recipiente de mensajes.

Un proceso recipiente de mensajes almacena una secuencia de números enteros transmitidos entre procesos por medro de l a s operaciones sendo y receive().

class BufEer : Process { int sz, cn, hd, tl, *st; void get(int&); void put(int); public: BuEer(int); void send(int); void receive(int&); 1;

Buffer::Buff;ir(int size) : Process (O) { cn = hd = It1 = O; st = new int[sz = size];

void B&er::put(int& c) { 1

st[tl] = c; tl=(tI+ I )%N; m++; 1

?

Page 155: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

void Buf€er::sen.d(int c) { select when (cn sz) put(c); 1

void BuEer::get(int c) { c = st[hd]; hd=(hd+ 1)%N; m”; 1

void Buffer:::receive(int& c) { select

when(cm > O) g m ;

Las operacion.es sobre el recipiente se pueden hacer así:

Buf3er b( 100:); intx=7; b.send(x); // envia el contenido de :x ...

b.receive(x); // recibe el contenido en x

Al igual que los semáSoros, después de iniciar sus variables el Buffer no requiere más el procesador, porque sólamente define las estructuras de datos y l a s operaciones sipficativas sobre ellas.

6.4 .3 . A d m i n i s t r a d o r de tareas.

Existe una gran variedad de proble~mas de admmstración de recursos que se pueden resolver mediante regiones protegrdas. Un recurso es por naturaleza “m cuello de botella” cuya rendimiento depende de que, o bien sean pocos los ]procesos que lo soliciten por mucho tiempo, o bien sean muchos procesos pero que lo usen por poco tiempo.

Page 156: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Un adrmnrstrador de recursos quc sigue la política el m& corto primero, (shortest job next) asigna un recurso a un número limitado de N procesos de usuarios. La solicitud del recurso request(} proporciona la identidad del proceso solicitante y el tiempo de servicio que requiere. La liberación del recurso releuse()indrca que e1 recurso se encuentra de nuevo disponible. El administrador usa las sigutentes variables: una lista de identificadores representada por un conjunto de bits queue , un arreglo de enteros para guardar el tiempo que cada procesct requiere rank , el índice del usuario actual (si lo hay ) user, y el indice del usuario siguiente next, La especificacion de la clase Set y de Scheduler se dan 15 continuación:

#define N 16 #define NIL -I #define MININT 32767 class Set {

int bits, size; public: Set(void) { bits = size = O ;

void include(int) { i f (O a= e && e a N) { bits (= I <<e; size++; 1 1 void exclu.de(int) { i f ( O <= e && e < N ) { bits &= -( 1 <<e); size--; 1 1

int contain(int) { if(0 <= e && e < N) retum(bits & (I<<e); 1 int card(void) { return(size: ); ] 1;

Set queue; int rmkpN]; int user, next; public Scheduler(void); void request(int, int); void release(void);

class Scheduler: Process {

1;

Una vez iniciadas las variables, el ,administrador espera hasta que una de dos situaciones tiene I u g a r :

a. Un proceso entra o sale de la lista queue: el administrador examinará la lista y seleccionará al siguiente usuario si es que lo hay. Sin embargo, esto no significa que el recurso se le asigne.

Page 157: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

b. El recurso no está siendo usado y el siguiente usuario ya había sido seleccionado: el administrador asigna entonces el recurso al proceso seleccionado y 110 remueve de la lista de espera.

Scheduler: : Scheduler(void) { user = next = NIL; for(; ;)

select { when(queue.catrd() > O && next = NIL 1 {

int i, k, min := MTNINT; for(i = O, k == O; i N && k 4 queue.card(); i++)

if(queue.c:ontain(í) && rank[í] <= min) { next = I.; min = rank[i]; k++;

) when(user = NIL && next != NIL) {

user = next; queue. exclude(user); 1

void Sche:duler: :release(void) { user = NIL;

1 void Scheduler::request(int who, int size) {

queue.ínclude(who); rank[who] = size; sselect when(user = who) next = NIL;

class User: Process { public: User( Scheduler&, kt);

);

Page 158: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Use~:::User(Scheduler& sjrb int id) { int r; for(int i = O; i < 100; i-t+;) {

r = random(5) +1; cout << id << "solicita el recurso por " << r "secs.\n"; sjn.request(id,r); cout << id << "usando el recurso por 'I << r << "secs. W'; delay(r); sjn.release();

El programa principal contiene solmnente declaraciones.

La adrmnistración de cada proceso se maneja en dos niveles de abstracción: al nivel de las operaciones request0 y release(), y al nivel de l a s regones protegdas con select. La evaIuac:ión periódica de la condrción de sincronización puede ser una seria sobrecarga para el rendimiento del sistema Sin embargo, es aceptable cuando se hace la distribución del procesamiento y un sólo procesadlor está dedicado a ello.

6 . 4 . 4 . Lectores y escritores.

Dos clases d'e procesos, llmados~ lectores y escritores, comparten un recurso. Los lectores pueden usar ell recurso simul&eamente, pero cada escritor debe tener acceso exclusivo a él. Los lectores y escritores se comportan como sigue:

Page 159: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Una variable S define el estado actual del recurso como uno de los siguientes:

s = o I escritor usa el rf:cwso

S = 2 1 lector usa el rec1urso s = 3 2 lectores usan el recurso

S = I O procesos usan el recwso

...

E1 anterior esquema da Iugar a la sipente soluci6n. El proceso Resource regula el paso de los lectores Reader y de los escritores Writer mediante l a s operaciones sturtreud, endread, startwrite, endwrite, respectivamente.

#define TIME 500 class Resource: Process {

int S;

pu.blic: Re:source(void); void startread(void); void endread(v0id); void startwrite(void); void endwrite(void);

class Reader: Process { 1;

public: R.eader(int, Resource&]);

1; class Writer: Process {

pujblic: W riter{int, Resource&);

1;

Page 160: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Las definiciones de los procesos y SULS operaciones son:

Resource::Resource(void): Process(0) {

1 S = I ;

void lXesource::startread(void) { select when(s )= 1) S++;

void Resource: :endread(void) { 1

if(s > 1) S.".

1 void Resource: :sta.rtwnte(void) {

sedect when (S = 1 ) S ==. O; 1

void lXesource::endwrite(vaid) {

I if(s = O) S = 1;

Readtx::Reader(char *id, Resource& book) { for(int i = O; i < 10; i++)

cout "Lector %S solicita recurso " id; book. startreado; cout << "Lector !/os usando el recurso " << id; delay(TIME); book.endwrite(); cout << 'I Escritor %S libera el recurso << id;

1 1

Writm::Writer(int id, Resource& book) { fix(int i = O; i < 10; i++) {

cout << Escritor %S solicita recurso I' << id; book , startwrite(); cout << "Escritor %S usando el recurso ... I' << id; delay(TIME); book.endwrite(); cout << "Escritor %S libera el recurso 'I << id; 1

1

Page 161: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

m h o

Resource book; for(int i = O; i < 10; í-t.+) {

new Reader(i,book); new Writer(i,book); 1

new Null(); 1

6 * 4 * 5 . Los f i l d s o f o s .

Cinco fil6sofos alternan sus activi<lades de pensar y comer. Cuando un filcisofo tiene hambre, se dirige a una mesa redonda y toma los dos cubiertos m(is cercanos al plato y comienza a comer. Sin embargo, sólamente hay cinco cubiertos en la mesa, a s i que un filóslofo sólo puede comer cuando ninguno de sus vecinos inmediatos lo esta haciendo. Cuando un filcisofo termina de comer, pone los dos cubiertos de nuevo en la mesa y la abandona La especificación de las clases Table y philosopher es como sigue:

class ‘Table: Process { Set eating;

Tdde(void); vo:id join(int); void leave(&);

public:

1;

public: class Philosopher: Process {

Plrtilosopher(int, Table&); 1.

El proceso Table usa la clase conjunto Set defimda en el ejemplo 5.4.3. El conjunto eating registra a los filósofos que se encuentran comiendo en la mesa Por esta razón, la operación join0 establece que es necesario esperar hasta que los dos filósofos que lo rodean hayan dejado de comer para que él pueda empezar. Cuando el filósofo abandona la mesa, se debe excluir del conjunto eating,

Page 162: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Table: :Table(void):Process(O) { // Actividad totalmente nula

void Table::join(int i) {

when(! eating.contain((i+4:) YO S) && !eating. contain((i+ 1) YA 5))

1

select

eating. include( i);

void Table::leave(int i) { eating. exclude(i);

1

El filósofo i aplica las operaciones tabZe.join(i) y table. Zeavec), en ese orden, para sincronizarse con los otros fil6sofos.

Philosopher: :Phdosopher(irlt id, Table& table) {

cout << "Filósofo %d hambriento I' << id; tabIe.join(id); cout << 'I Filósofo %di comiendo ... I' << id; delay(T1ME); table.leave(id); cout << " Filósofo %d. pensando 'I << id; delay(TIME);

for(i = O; i < 10; i++) {

1 1

Los filósofos se pueden crear cctmo un arreglo de procesos, o más exactamente, como un arreglo de apuntadores a procesos Phlosopher. Observe, que este programa no necesita realmente conocer las hrecciones de los filósofos por lo que podemos prescindir de arreglo.

mainlo { Table table;

for(int i = O; i < 5; i++) new Philosopher(i, table); new Nullo;

1

Page 163: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

La solución que se presenta no previene que dos filósofos coman alternativamente., impidiendo que coma el filósofo que se encuentra en medio.

6.4.6. Ordenamiento de un a r r e g l o .

Un arreglo de procesos puede ordenar un arreglo en un tiempo proporcional al t'amaño de un arreglo tie datos. Los datos se envían al primer proceso del arreglo quien conserva al menor de todos ellos y pasa el resto al segundo. Más tarde, el segundo proceso conserva el menor de los datos que ha recibido y envía el resto al siguiente, y así sucesivamente. Cuando se agotan los datas del arreglo, cada proceso mantendrá el dato que le corresponde de acuerdo con su orden natural: el primer proceso conserva el menor de los datos, el segundo conserva el dato que le sigue, etc. Para recuperar los datos ya ordenados, so1ic:itamos los datos al primer proceso del arreglo quien res'ponderá de inmedata con el dato que guarda Más tarde, el segundo proceso envía el dato que guarda al primer proceso. Este procedimiento hace que los datos st: muevan hacia los predecesores del arreglo hasta que: finalmente se agotan los datos.

class Sort: Process { int kere[2], length, rest, temp; public: Sort(int); void put(int); void get(&&);

1; sort* sortpi];

El proceso Sort usa la variable here para guardar los datos que recibe, length para indlcar el número de ellos,. rest es el número de datos pasados a sus sucesores y temp contiene el dato que será pasado a su sucesor. Las operaciones put() y get0 envian y reciben los datos hacia y del proceso, respectivamente. La variable global sort es el arreglo de N apuntadores a los procesos que rdiizarán el ordenamiento.

Page 164: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

class User: Process { public: User(void);

1; El proceso de: usuario User envía y recibe los datos al primer proceso del

arreglo con l a s llamadas sort[U]->put() y sort[U]->geto, respectivamente. User define el aureglo a de M enteras que serán ordenados. El número de elementos del arreglo M debe ser menor al número de procesos N.

User: : User(voíd) { int i, GM] = (6,2,7,9,3,:5,8,1,0,4);

cmut << "\n\nArreglo d.esordenado: "; for (i = O; i < M; i++)

cout << gil; for(i = O ; i < M; i++)

sort[O]->put(a[i]):, far (i = O; i > M; i++)

sort[ O]->get( a[_í]); ,( sigue ... ) I( continúa ...

cout .<< "h Arreglo ordenado: "; for(i = O; i < M; i++)

cout << a[i]; 1;

Un proceso del arreglo se encuentra en equilibrio cuando guarda un dato nada más. Dicho equilibrio se ve alterado por el proceso predecesor cuando le envía un dato 01 cuando se lo solicita, Para recuperar el equilibrio, se debe tener en cuenta d.os situaciones:

a. Si el proceso posee dos tiatos, mantendrá el menor de los dos y

b. Si e l proceso no posee ningún dato pero su sucesor si, entonces pasará el mayor a su sucesor.

se lo solicita a él.

Page 165: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

El índice succ (determina el proceso siguiente.

sort::tsort(iIlt succ) { length = rest = O; for(;;);

select { when(1ength = 2) {

if(here[O] <= here( 1));

else { temp = here[ 11;

temp = her-e[O]; here[O] = here[ 13; 1 length--; s~rt[succ]-~put(temp); rest++;

when(1ength == O && rest> O) { sort[succ]-~gf:); rest--; hereto:! = temp; length++;

1 li

1 void Sort::put(int c) {

se:lect when(1ength 2) { here[length] = c; length++; 1

1 void Sort: :get(int& c) {

select when ( l e n g t h = 1) { length--;

1 c = here[length];

Page 166: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

maill() {

for(& i = O; i < N; i++)

new User(); new Null();

sort[i] = new Sort(i+l);

6 . 4 . 7 . Construcciún d i n g m i c a de procesos.

El lenguaje C++ concurrente permite construir procesos a tiempo de ejecucion. A &ferencia de los qempbos anteriores, es posible que un proceso construya a otra ( inclusive de otra clrtse) medtante las hciones new y delete. Para demostr~lio, presentamos el ejelmplo clásico del programa. factorial que crea nuevos procesos en forma recursiva

class Factorial: Process { Factorial* factorial; !semaphore* next; public: l?actorial(long n, long& r, Semaphore* prev); 1:

Factorial::Fac:torial(long n, long& r? Semaphore* prev) { if'n = O) {

r = 1 ; prev-->signal();

3 else {

next -= new Semaphore@); factorial = new Factorial(n - 1 ~ r next); next->wait(); r = n * r ; prev-.>signal(); delete factorial; delete next;

1 1

Page 167: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

class Caller { Factorial* factorial; Semaphore* next; pub1i.c: Calle:r(long n ,long& r)

j ; Caller::Calller(long n, long& r) {

next = new Semaphore@); factorial = new Factorial(l1, r, next); next->wait(); delete factorial; delete next;

1 maw)

long in = I O, r;

hldl os; Calller factorial(n,r);

tout << "Factorial(" << n << ")=" << r; 1

El proceso fictorial de n, crea a un semáforo #ex& y a otro proceso factorial para n - l . El pmámetro nse envía del factorial de n al factorial de n - 1. El parámetro iv lo recibe el factorial de n del factorial de n -1. El semtiforo next, sincroniza a los procesos, de modo que el factorial de n espera a que el factorial de n- 1 calcde el resultado. Cuando esto ocurre, el factorial de n reanuda su ejecución. El proceso C Z Z w sólo se usa para iniciar las 1la.madas d Factorial.

Los dos ejem;plos anteriores demuestran algunas de las capacidades del C++ concurrente:: (I), la creación y derstrucción hámica de procesos, (2), la topología dinámica, y (3) la comunicación síncrona bidrreccional.

Page 168: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

6 . 4 . 8 . Trayectorias ( F ' d t h expressions)

Las trayectorias defmen secuencias de operaciones similares a l a s expresiones regulares Las trayectorias se pueden representar por procesos que definen las operaciones y de variables de estado que sincronizan su actividad estableciendo un orden en la ejecucibn de las operaciones.

Secuencia. Supongamos que la operacibn P debe ejecutarse antes que la operación Q, colmo se muestra en la figura,

en el lenguaje C++ Concurrente se puede obtener m esquema corresponhente,, introduciendo estado:s (a, b, y c)

-> [ S == a] P -> [S b] Q ->

y usando regiones críticas

Path::P() { select when ( s = a ) { .--; s = b; ) Path::Q() { select when ( S = b) { ...; S = c; ] 1

Alternativas. :El dragrama que sigue: indica que tanto la operacicjn P corno la operacibn Q pueden ejecutar en un momento dado.

que corresponde a

Path::P() { select when ( s = a,) {...; s = b; f f Path::Q() .[ select when ( S = 11) { -..; S = 6; ) )

Page 169: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Repeticiones. El siguiente diagrama. muestra la repetición de la operacibn P cero, una o más veces.

que corresponde a

Path;: :PO { select when (S = a) { . . . 1 1

Idas trayectorias pueden usarse para. ambientes de programación visual que se basen en algún modelo de concurrencia para imponer un orden en su evaluación. El administrador de recumos presentado en el ejemplo 5.4.3 se puede representar por medio de trayectorias formadas por la secuencia de operaciones request0 . . . releaseo de cero, una o m& ocasiones.

El problema de los lectores y escritores ilustra el uso de variables de estado que permitan que algunas operaciones tengan lugar simultheamente mientras otras son excluidas. Por ejemplo, varios lectores pueden operar simultáneamente excluyendo a los escritores, o bien, que un escritor puede excluir a los lectores.

6 . 4 - 9 . Otro ejemplo: <el problema d e l productor- consumidor

El escenario del problema consta de dos procesos, el primero es un productor de inlkrmación, y el segundo es el consumidor de la misma. La variante más conocida de este problema emplea un recipiente (bizffer) de almacenamiento limitado entre ellos que divi% en parte, l a s dferencias de velocidades de operación del productor y el consumidor.

El programa comienza dando las especificaciones de l a s tres clases procesos: recipiente (Búfler), productor (Producer) y consumidor (Consumer). Cualquier tipo de proceso debe derivarse de la clase Process.

class Buffer: Process { int CII, sz, hd, tl, *st; public: Bwfl:Pr(int); void. get(int&);

Page 170: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

void put(&); 1;

class Producer: Process { int c; pub1 ic; Prociucer(BuEer&, char*);

I ; class Consumer: Process {

int c; public: Consumer(Buf€er&); 1;

Bufler el proceso que sirve para almacenar y recuperar la información usando una cola, circular implantada con un arreglo. El estado del proceso Io constituyen los valores de las variab1.e~ componentes: cn es el contador de datos disponibles en el almacén, sz es el número máximo de datos que se pueden guardar, hd y tl son 10s apuntadores al primer y ultimo datos guardados en el: almacén st. Los servicios deben solicitarse a través de los procedimientos públicos get0 y put(). Obsérvese que el paso de parámetros en get0 es por valor ya que los datos son enviados d Bufler, en tanto que el paso de parhetros en get0 es por re:ferencia ya que los datos son recibidos por allí. Por otra parte, la estructura dle los procesos Producer y Consumer es muy simple ya que necesitan h icmal te de la variable componente c.

El comportanliento de las clases de objetos se establece en la dehci6n de las hciones constructoras. Las fimciones constructoras de las clases derivadas de Process llaman directa o indirectamente a s u constructor

BdTer::B;uf€er(int size):Process(O) {

st =I new int[sz = size]; cn := kd = tl = 0.

7

1 Producer: :Producer(R&er& bl, char *p) {

c .= * ++. P ? uhIe(c != O) f

b.put(c); c = *p-tt; I 1

Page 171: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Consum.er::Consumer(Buffer& b) { b.get(c); while (c != O ) {

putc.har(c); b.get(c); 1

1

La fúncih cortstructora de Bufler hace una llamada explícita a.l constructor de la clase base ::Process@) indicando que el tmaiio de la pila para los procesos de este tipo es cero. Esto sigmfica que los procesos de este tipo no necesitan gurudlu el estado de su procesamiento ya que se dedican hicmente a prt:star servicios. Despub de la iniciación de las variables de estado, el proceso no competirá más por el uso del procesador a b cuando otros puedan solicitar los servicios get!:) yputd).

La hci6n constructora de Producer establece que el proceso toma los caracteres que recibe a través de su parámetro p y los envía al recipiente b usando el servicio put(). Esta secuencia se repite hasta agotar la cadena. Por último, la función constructora de C'un2;surner toma los datos depositados en h usando el servicio get().

Los servicios get() y put() definen los métodos de acceso a una cola circular. En la fimcibn get(), se debe cumplir la condicih de que existan datos disponibles mtes de que el proceso cliente pueda recibir el servicio. Si no hay ningh dato disponible, el cliente se ve obligado a esperar hasta que haya por lo menos uno. Entonces, el cliente puede entrar al bloque protegido por el Único guardia. En forma simila? Ia fünciian put() usa un ,guardia para impedir que no se inserten mis datos de los que puede almacenar el recipiente.

void E3ufkr::get(int c) { select when (cn O) {

c st[hd]~ hd = (hd + I> Y6 SZ; cn--; 1

1 void ~Bu.Eer::put(int& c) {

select when (m sz) f st[tl] = c; tl = (tl + I) YO sz; cn++; 1 I

Page 172: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

El programa principal declara ~tn proceso de cada clase. El C t + Concurrente define una clase para representar al proceso nulo. El proceso nulo es en realidad el sistema operativo anfitnón suspendido temporalmente. La solicitud de cualquier servicio del sistema operativo debe dirigirse al proceso nulo. Sin embargo, para reducir el cuello de botella que puede ocurrir, las operaciones como las de entrada y salida que utilizen los dispositivos estándares ( el teclado y la consola), l a s funciones de la biblioteca estándar, y en ,general, aquellas operaciones que no manejen archvos, se pueden realizar directamente por el proceso solicitante. La memoria pedida par new es solidda al proceso nulo en forma transparente y es la forma como se debe realizar en el C++ Concurrente. Obsérvese que el proceso nulo debe ser el último en declararse.

main.() { Blfler b; Producer p(b,"0123456:789"=; Consumer c@); Nldl os;

I AI principio de la ejecución, el recipiente se encuentra vacío por lo que

sólamente podria prestar el servicio puto. Si el consumidor solicitara la operacibn get(), entonces se vería obligado a esperar hasta que hubiera algún carácter dsponible. Cuando el productor envía un carkter? el recipiente lo acepta y esto ocasiona que su estado cambie. En este momento, las condiciones que vigilan los guardias de put() y get0 son m b a s verdaderas y cualquiera de ambos, el productor o el consumidor, podrían obtener los servicios. En estle caso, la elección del siguiente a ejecutarse se realiza al azar. Finalmmte, los procesos tenninan cumdo alcanzan el final del bloque de su definiciiin.

Page 173: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

7. C Concurrente.

El lenguaje C Concurrente h é Qseiiado en los laboratorios Bell en 1984 y se han redizado diferentes implantaciones de su compilador entre 1985 y 1986. Los autores Gehani y Roome extendieron aJ lenguaje C para hacer posible la concxrencia, agregando construcciones nuevas que permiten declarar, crear, destruir y sincronizztr procesos. Este lenguaje ofrece un mecanismo de abstracción de datos.; sin embargo, l a s implantaciones del compilador perrniten hacer un preprocesamiento que acepta los estatutos del lenguaje C+ +.

Un proceso en el lenguaje C Ccvtcurrente consiste de dos partes: su especificación d,e tipo y su dehción. Un proceso no se crea por el hecho de especificar su tipo; el programador debe crearlo explícitamente mediante un operador. Este l&guaje no define una política de administración de procesos. Los procesos interactúan por meho d.e encuentros ó transacciones, como le llaman los autores. IJna trgnsuccidn e; un medio de acceso a un servicio. Hay dos tipos de transacciones: sincronas y asíncronas. Un proceso que solicita una transaccidn stncrona se bloquea hasta que el proceso acepta la transacción y ejecuta el bloque de estatutos que tiene asociado. En una transaccidn ashwona, el proceso contmúa luego de solicitar la trunsuccidn.

process spec buEer() { trans void put(& c); trans int get(void);

15

proctzss spec consumer(process buyer 9); process spec producer(process buffer 9);

process body buffer() { int s;t[n]; int cm, hd, tl; cn == hd = tl = O; for( ;;)

Page 174: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

select { (cn < N) : accept put(c>;

st[hd] = C; hd = (hd + I) Ya N; cn++; or (cn > O) : accept get();

retum st[tl]; tl '= (tl + I) YO N; m--; 1

1

proc:ess body producer(q) { int c;

do { c = q.get(); printf("Conswne %c \n 'I, c); 1 while(c != EOF);

1

main0 { process buffer q; q = create bee@); create consumer(q); create producer(q);

1 En el programa anterior, el proceso bufler tiene dos transacciones, puto y

get(). puto pone un carácter en el recipiente; si el recipiente está lleno, la transaccih no se realiza en tanto no haya espacio drsponible. get() toma un caracter del recipiente; si el recipiente está vacio, esta transacción no se realiza hasta que haya un carácter disponible. El proceso bufler ejecuta repetidamente ell estatuto select, el cual presenta dos alternativas separadas con la palabra reservada or. Cada altemativa comienza con un guardia seguida de un estatuto accept. El ,guardia prueba si la conddn se ha cumplido, en cuyo caso, se ejecuta el grupo de estatutos que le siguen. Si la condición no se ha cumplido, el estatuto select escoge otra alternativa Si no se verifica ninguna con&cion, el comportamiento queda indefinxdo. Por otra parte, tambih es posible que más de una condici6n se verifique: en este caso, el estatuto selecl' escoge alguna alternativa no detenninisticamente. El estatuto return regresa el vdor determinado por la transacción get@

Page 175: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

La comparación se hará de acuerdo a los criterios generales de &s&o de un lenguaje de programacion: modelo de programación, segundad, complejidad, exprcsividad y cficiencia..

7 . 3 . 1 . Model o de prog~ramac ión

El modelo es el fundamento de un lenguaje de progrmacibn. En 61 se consideran el tipo de problemas o enfoque R que se orienta el lenguaje, las propiedades que poseen los objetos involucrados, los mecanismos de creación y destruccibn, se existencia y hbi to así como las operaciones entre ellos.

a Ambos modelos permiten la abstracción de datos. El lenguaje C + + Concurrente está construido sobre el lenguaje orientado a objetos C++. El lenguaje C Concurrente acepta construcciones del C++ pero no plantea n i n e modelo unificado de objeto y proceso.

b. Ambos modelos usan las regiones protegidas como medio de sincronizacibn y el paso de mensajes como medio de comunicacibn. Ambos lenguajes usan e:l modelo de paso bidxreccional de mensajes que es la esencia del modelo de llamada a procedimiento remoto. El modelo de llamada a procedimiento remoto usado en el C++ Concurrente es sirnilar en vasios aspectos al C Conctrrrente de Gehani, aunque existen algunas diferencias importantes. En el C++ Concurrente, una llamada a un procedimiento remoto se acepta inmehatamente aunque su ejecucion puede no comenzar de inmediato. Si 1'10 comienza de inmediato, el proceso solicitante queda suspendido de esta forma. La ejecucibn comienza tan pronto como se verifiquen las condxiones de sincronización establec.idas en el estatuto select. La ejecución de: un nuevo proceso, 'u otro previamente suspendido, puede iniciarse o reanudarse, respectivamente. Durante la ejecución del procedimiento, 121 proceso solicitante puede suspenderse y reactivarse varias veces antes de que pueda completarse. Por otra parte, en el C Concurrente, l a s l l a m a d a s A, los procedlmientos no se aceptan mientras el proceso no esté listo para hacerlo, es decir, mientras no se cumplan las condiciones de sincronizacibn que é1 establece, CJna vez que la aceptIt, &a se ejecuta hwta su témino.

Page 176: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro
Page 177: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

b. La simplicidad del lenguaje reduce el tamaiío del compilador haciendolo m& rápido y G.cil de escribir, lo que redunda en el aumento de su Qsponibilidad. E h el C+ + Concurrente no se realiza otro preprocesmiento como ocurre en el C Concurrente que no sea el propio C++ ( swtituciones literales causadas por #define ).

c. La consistencia es una consecuencia de la reducida complejidad del lenguaje. Esto se revela en la facilidad para aprender a usarlo, debido al menor n h e r o de excepciones que se deben tener en cuenta al escribir un programa. El enfoque de Gehani y Roome no parece producir un lenguaje menos complejo. No se propone ninguna unificación entre los conceptos de objeto y proceso, por lo cual, ofrecen reglas propias para la declaración y el uso de cada uno.

7 . 3 . 4 . Expresividad.

Un lenguaje debe ser suficientemente expresivo para poder formular todas l a s operaciones que se requieran en un programa con el menor número posible de símbchs.

a El lenguaje propuesto por Gehtrni y Roome es más expresivo que la versión actual del C++ Concurrente. El estatuto select posee variantes poderosas que permiten describir situaciones complejas con pocas lineas de códlgo.

Un ejemplo es el controlador de l u n drspositivo que debe coordrnar los motores en las aplicaciones de tiempo real. Generalmente, se deben apagar los motores de algún proceso para e:l ahorro de energía El estatuto select permite esperar cierto tiempo hasta que no ocurra alguna transaccih mediante la cláusula dela-v.

h. Las futuras implantaciones tratarán de no agregar demasiadas reglas de sintaxis al lenguaje tratando de conservar la misma complejidad, aprovechando para esto, el enfoque d.e la orientación a objetos. El problema anterior se puede resolver introduciendo dos clases: la clase Timer, para este tipo de problemas, en particular. Un objeto de esta clase regresa el valor cero hasta que no haya cumplido cierto plazo cambiando entonces a uno.

Page 178: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Este comportamiento hace posible que puedan aparecer expresiones que involucren al tiempo en los guardias. En forma similar se pueden resolver otros problemas tie tiempo red.

Los progamas concurrentes deben tener una buena implantacibn evitando situaciones que tien lugar a tiempos tie ejecución mayores a los tolerables sobre todo en aplicaciones de tiempo real.

Es nec.eswio reconocer que éSta es una desventaja definitiva de la impiarttacih achd del C++ ¿,'oncurre?nte con respecto al (1 Concurrente de Gehani. Es muy ineficiente el acceso a l a s repones protegdas por guardias debido a la sobrecarga introducida por el no determinisme implantado. Además, el administrador de memoria también es un tanto ineficiente. Esto se debe al intento de pardar la cmnpatibilidad con el ambiente de ejecución diseiiado para correr programas en C t f- .

Page 179: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

PROYECTO DE INVESTIGACION I1

COMPILADOR CONCURRENTE

PARA LENGUAJE

PALSCAL CONCURRENTE

REALIZADO POR:

MONROY MERCADO JOSE LUIS P.

TRIMESTRE: 94-P.

Page 180: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

I . INTRODUCCI~N.

El siguiente documento describe un nuevo lenguaje de programación. Este es una extensión del lenguaje de Progrmaci6n Pascal con

herramientas de programación llamadas procesos y monitores. La principal contribución de Pascal Concurrente es extender el concepto del monitor con una jerarquía explícita de derechos de acceso a las estructuras de datos compartidas que pueden ser dec:laradas en el texto del propama y ser verificadas por el compilador.

1 . 2 EL PROPbSITO DE PASCAL CONCURRENTE.

2.2-1 ANTECEDENTES.

Desde hace tiempo se ha estado trabajando con un nuevo Ienguaje de programación estructurada para microcomputadoras. Este lenguaje es Ilmado Pascai! Concurrente. Este lenguaje extiende el lenguaje de programación !secuencial Pascal con herramientas de programación concurrente llmadas procesos y monitores.

Esta es una descripción de Pascal Concurrente. En esta se usan ejemplos, gráficas, y palabras para brindar los aspectos creativos de los nuevos conceptos de programación. Se planea definir estos conceptos precisamente e introducir una notación para &tos.

P. 2.2 E’ROCESOS.

Veremos nuestro estud.10 de procesos concurrentes mediante m ejemplo de un problema: ¿que tanta cantidad de datos pueden ser transmitidos desde un proceso a otro por medio de un buffer en un disco?

La figura 1 muestra este pequeño sistema y sus tres componentes: un proceso que produce datos, un proceso que consume datos, y un b&er de disco que los conecta.

Page 181: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

O

O o Figura l . Comunicación entre procesos

Los circulos son Componentes de sistema y las flechas son los derechos de acceso de esols componentes. Se inuestra que ambos procesos pueden usar el buffer ( pero ]no muestran que datos fluyen del productos al consumidor). Este tipo de gráfica es una gr&fica de acceso.

La siguiente figura muestra un componente de sistema con más detalle. @figura 2).

Derechos de acceso Datos privados

Programa secuencial

Figura 2. Proceso.

Un proceso consiste de una estrzrctura de datos privada y un programa secuenciul que puede operar sobre los datos. Un proceso no puede operar sobre los datos privados de otro prcxeso. Pero los procesos concurrentes pueden comparbir ciertas estructuras de datos (como un buffer de drsco). Los derechos de acceso de un proceso hacen referencia a los datos compartidos sobre los que puede operar.

Page 182: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Un buffer de &sco es una estmctura de datos compartida por dos procesos concurrentes. Los detalles de cómo tal buffer es construido son irrelevantes a sus usuarios. Todos los procesos necesitan conocer si pueden enviar {send} y recibir {receive} datas a través de &e. Si ellos tratan de operar sobre el buffer de cualquier otra forma es probable que ocurra un error de programación 6 un ejemplo de programación engañosa. En ambos casos, el compilador debe de detectar tales malos usos de la estructura de datos compartida

Para hacer esto posible, introducimos un lenguaje constructor que permitira al programador decirle al co.mpilador cómo las estructuras de datos compartidas pueden ser usadas por los pocesos . Este tipo de componente de sistema es llamado monitor. Un monitor puede sincronizar procesos concurrentes y transmitir datos entre ellos. Esto puede controlar el orden en el cual los procesos que compiten entre sí usan los recursos fisicos, compartidos. La figura 3 muestra un monitor en detalle.

Derechos de acceso Datos compartidos

Operación inicial Operaciones de sincronización

Figura 3. Monitor.

Un monitor defíne una estructura de datos compartida y todas las operaciones de 110s procesos pueden hacerse sobre él. Estas operaciones de sincronización son llamadas procedimientos del monitor. Un monitor define una operucidn inicial que será ejecutada cuando su estructura de datos es creada

Así podemos definir un buffer de disco como un monitor. Dentro de este monitor abrá variables compartidas que definen la localidad y el tamaño del b e e r en el (disco. Habrá dos procedimientos del monitor, send y receive. La operación inicial estará segura de que el buffer empieza estando vacío.

Page 183: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Los procersos no pueden operar directamente SS datos compartidos. Pueden sólamente llamar a los rpocechmientos del monitor para que tengan acceso a los datos compartidos. Un procedimiento de un monitor es ejecutado como parte de un proceso que hace la llamada ( justo como cualquier otro procedimiento ).

Si los procesos concurrentes llaman a los procedimientos del monitor simultáneamente para que operen sobre los mismos datos compartidos estos procedimientos ldeben ser ejecutados estrictamente uno a la vez. De otra manera, los resdtados de las llamadas al monitor son impredecibles. Esto significa que la máquina debe permitir que los procesos esperen por periodos de tiempo cortos hasta que puedan ejecutar los procedrmientos del monitor. Nótese que un procedimiento de un monitor tiene acceso exclusivo a los datos compartidos mientras éste se ejecuta.

Entonces la máquina ( virtud ) sobre la c d se ejecutan los programas concurrentes deberá tener un scheduler para las diferentes llamadas del monitor. Pero el programador debe permitir a los procesos que esperen por largos periodos de tiempo si sus requerimientos de datos y otros recursos no pueden ser satiskchos inmediatamente. Si, por ejemplo, un proceso intenta recibir datos desde un buEer vacío, el proceso deberá esperar hasta que otro proceso mande más datos al bufk .

Pascal Concurrente incluye un tipo de datos simple, llamado una cola (queue), que puede ser usada por los procedimientos del monitor para controlar la organización de los procesos. Un monitor puede hacer cualquiera de las dos cosas sigutentes: suspender (deby) a un proceso que hace una llamada, en unat cola, ó continuar (continue) con otro proceso que esta esperando en una cola. Recordemos que un proceso tiene acceso exclusivo a 10s datos compartidos tanto como éste continúe ejecutando las sentencias del procedimiento d.el monitor. Tan pronto como un proceso sea suspenddo en una cola &te pierde sus derechos de acceso exclusivo hasta que otro proceso llame al mismo monitor y lo despierte otra vez. ( sin esta regla sería imposible para otros procesos entrar al monitor y esperar a que los procesos continúen su ejecución).

Aunque el ejemplo del buffer de &sco no muestra &o, los procedimietos del monitor deben ser capaces de llamar procedimientos dentro

Page 184: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

de otros monitores. De otra forma el lenguaje no será usado para diseño jerárquico. En el caso del buffer del disco, uno de esos otros monitores deberá permitir definir operaciones simples de entraddsalida en el drsco. Entonces un momitor puede tener derechos de acceso a otro componente de sistema. (ver figrrra 3).

2.2.4 DISEÑO DEL SISTEMA.

Un proceso ejecuta un programa secuencial -este es un componente activo. Un monitor es sólo una colecci¿in de procedmientos que no hacen nada hasta que son llamados por procesos -son una componente pasivo. Pero hay similaridades kertes entre un proceso y un monitor: ambos definen una estructura de datos (privada o compartida) y l a s correspondmtes operaciones sobre ésa La principal diferencia entre los procesos y los monitores es la forma en que son organtzados para ejecución.

Esto parece natural bajo el hecho de que los monitores y los procesos son definidos como tipos de datos abstractos en términos de l a s operaciones que puedan realizarse sobre ellos. Si m compilador puede verificar que éstas operaciones sean las únicas llevadas a cabo sobre las estructuras de datos, entonces estaremos redmente permi.tiendo la construcción de programas concurrentes en los cuales el xceso controlado a los datos y a los recursos fisicos estará garantizado antes de que estos programas sean puestos en operación. Tenemos entonces alguna solución al problema de proteccidn de recursos en la mejor manera posible (sin mecanismos de hardware y sobreflujos a tianpo de ejecución).

Entonces cdefimremos a los procesos y monitores como tipos de datos y haremos posible el uso de varias instancias del mismo tipo de componente en un sistema. Podemos, por ejemplo, usar dos buffers de drsco para construir un sistema de spooling con un proceso de entrada, un proceso de trabajo y un proceso de salid,a (figura 4).

Page 185: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

lecbrdebrjctrs B& de disco

a O O

O O O

Figura 4. Sistema de Spooling.

Haremos distinción entre defjniciones e instancias de componentes llamando a estos; tipos de sistema y componentes de sistema. Las gráficas de acceso (como IEL figura 4) siempre mostrarán componentes de sistema (no tipos de sistema).

Los dispositivos periféricos son considerados como monitores implementados tm hardware. Ellos pueden ser accesados sólo por un simple procedimiento i o que suspende al proceso que hace la I l a m a d a hasta que una operación de mtraddsalida es completada Las interrupciones son manejads por la máquina virtual mientras corre d proceso.

Para usar el lenguaje de programación por pasos de &seÍí0 de sistema este deberá permitir la división de un tipo sistema, como el buffer de &sco, en pequeiios tipos sistema Uno de estos otros tipos sistema debera dar al buffer de disco acceso al disco. Llamaremos a este tipo de sistema un disco virtual. Da al buffer la i:lusión de que tiene su propio &sco privado. Un disco virtual esconde los d&dles de la entraddsalida de &sco al esto del sistema y hace que el disco Iusca como una estructura de datos (un arreglo de páginas de disco). Las únicas operaciones sobre esta estructura de datos son Zeer y escribir una págiina

Cada &so0 virtual es únicamente usado por un simple buffer de disco (figura 5). Un. componente de sistema que no puede ser llamado simultáneamente por otros componentes de sistema será llamado una clase (chss). Una clase defíne una estructura de datos y l a s posibles operaciones sobre &a (justo como en un monitor).

Page 186: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

Figura 5. Refinamiento del bufFer.

El acceso exclusivo de los procedimientos de la clase a las variables de la clase puede ser garantizado completamente a tiempo de compilación. La miquina virtud no tiene las llamadas simultáneas de organizacion de procedmientos 'de clases a tiempo de ejecución, porque tales llamadas no pueden ocurrir. Esto hace que las llamadas a las clases sean considerablemente más rápidas que las llamadas a monitor.

1.2.5 REGLAS DE ALCANCE.

El manejo de procesos hhicamente complica la semántica y la implementacibn del lenguaje de progrmacion considerablemente. En los lenguajes de progrmacicin existentes l a s estructuras de datos de losprocesos, monitores y clases son llamadas "datos globales". Este término es adoptado por Pascal Concurrente donde cada estructura de datos puede ser accesada por un simple componente sólamente. Esto hace más apropiadas las llamadas a estas estructuras de datos permanentes.

El aspecto más peligroso de la programacibn concurrente es la posibilidad de tener errores de programacibn dependientes del tiempo que son imposibles de localizar por una prueba del propma Mortunadamente un compilador puede detectar muchos de estos errores si los procesos y monitores son rt:presentados por una notacion estructurada en un lenguaje de programación de alto nivel.

Un compi:ldor de Pascal Concurrente verificarti que los datos privados de los procesos sólo sean accesados por un proceso. Este verificará que l a s estrumas de datos de clases y monitores solo sean accesados por sus propios procedimientos.

Page 187: CONTENIDO - 148.206.53.84148.206.53.84/tesiuami/UAM7310.pdf · 4. ada. 1980. 4.1 el lenguaje de programacion de la decada de 4.2 motivaciones para la multitarea en ada. 4.3 el encuentro

1.2 6 OBSERVACIONES FINALES

La principd contribucibn de Puscal Concurrente es la extensi6n de los monitores con los derechos de acceso explicitos que pueden ser verificados a tiempo de compilacicjn.

Cuando escribimos un programa concurrente debemos poder representar l a s reglas de acceso con ut texto. Esta limitacibn de escritura del lenguaje tiende a. oscwma la simplicidad de la estructura original.