560 likes | 733 Views
Concurrencia en Ada. Tareas. En Ada, las actividades concurrentes se describen por medio de tareas La forma de expresar una tarea en Ada es similar a los paquetes:. task T is --especificación end T ; task body T is --cuerpo end T; . Tareas. Cada tarea consta de:
E N D
Tareas • En Ada, las actividades concurrentes se describen por medio de tareas • La forma de expresar una tarea en Ada es similar a los paquetes: task T is --especificación end T; task body T is --cuerpo end T;
Tareas • Cada tarea consta de: • Una especificación que describe la interfaz que presenta a otras tareas • Un cuerpo que describe el comportamiento dinámico de la tarea • En algunos casos una tarea no presenta interfaz a otras tareas task T; task body T is --cuerpo end T; task T is --especificación end T; task body T is --cuerpo end T;
Tareas • Declaración • Activación • Terminación
Declaración de tareas • Una tarea es un componente de programa que puede declararse dentro de: • subprogramas, bloques, paquetes o dentro del cuerpo de otra tarea
Ejemplo • Arreglos en una casa: colocar pisos, colocar molduras, colocar cocina
Ejemplo procedureARREGLAR_CASAis taskALBAÑIL; task bodyALBAÑILis begin COLOCAR_PISOS; endALBAÑIL; taskYESISTA; taskbodyYESISTAis begin COLACAR_MOLDURAS; endYESISTA; taskMONTADOR; task bodyMONTADORis COLOCAR_COCINA; endMONTADOR; begin SUPERVISAR_TRABAJOS; endARREGLAR_CASA; procedureARREGLAR_CASAis COLOCAR_PISOS; COLACAR_MOLDURAS; COLOCAR_COCINA; SUPERVISAR_TRABAJOS; endARREGLAR_CASA;
Activación de tareas • La ejecución de una tarea puede entenderse como un proceso que consta de dos fases: • La primera fase, conocida como activación, consiste en la elaboración de las declaraciones del cuerpo de la tarea • La segunda fase consiste por supuesto en la ejecución de sus sentencias • La activación de una tarea es automática • Las tareas “subordinadas” se activan automáticamente cuando la unidad “progenitora” llega al begin siguiente a la declaración de las tareas
Activación de tareas • Cuando una tarea se declara en un paquete, su activación se produce en el begin del cuerpo del paquete
Activación de tareas procedureARREGLAR_CASAis taskALBAÑIL; task bodyALBAÑILis begin COLOCAR_PISOS; endALBAÑIL; taskYESISTA; taskbodyYESISTAis begin COLACAR_MOLDURAS; endYESISTA; taskMONTADOR; task bodyMONTADORis COLOCAR_COCINA; endMONTADOR; begin SUPERVISAR_TRABAJOS; endARREGLAR_CASA; • Activación de las tareas: albañil, yesista y montador • Un vez activadas la tareas existirán 4 tareas ejecutándose concurrentemente
Terminación de tareas • Las tareas “terminan” cuando llegan a su end final • Regla importante: • “Una unidad no puede acabar hasta que todas las tareas dependientes de ella hayan terminado”
Terminación de tareas • En general podemos decir que la terminación se realiza en dos etapas: • Diremos que una unidad se completa cuando llega a su end final • y finalmente terminará sólo cuando todas las tareas dependientes, si las hay, hayanterminado también
begin Principal declaraciones end tarea A declarada activación ejecución tarea B declarada activación ejecución Ejemplo procedurePRINCIPALis --declaraciones ... taskA; task bodyAis begin ...; endA; taskB; taskbodyBis begin ...; endB; begin ...; endPRINCIPAL;
La cita (rendez-vous) • Generalmente las tareas interaccionarán entre sí durante su tiempo de vida. • Esto se hace en Ada mediante un mecanismo conocido como la cita o rendez-vous (que significa sincronización e intercambio de información entre dos tareas dadas)
Puntos de entrada • La cita entre dos tareas se produce como consecuencia de la llamada de una tarea a un punto de entrada declarado en otra tarea • Se declara un punto de entrada en la especificación de una tarea de la misma manera que se declara un procedimiento en la especificación de un paquete taskEJEMPLO is entry SIN_PARAMETROS; entryCON_PARAMETROS(A:in INTEGER;B:out FLOAT; C:in out BOOLEAN); private entry .....; endEJEMPLO;
Puntos de entrada • Un punto de entrada puede tener parámetros in, out e in out • Los parámetros son el medio para el intercambio de información entre las tareas que se den en la cita • Si en la declaración de un punto de entrada no hay parámetros significa que estamos utilizando el punto de entrada únicamente para sincronización entre tareas
Sentencias accept • Las sentencias que se ejecutarán durante una cita se describen mediante las sentencias accept correspondientes • Las sentencias accept se encuentran en el cuerpo de la tarea que contiene la declaración del punto de entrada correspondiente task bodyEJEMPLOis begin ... acceptSIN_PARAMETROSdo --conjunto de sentencias que se ejecutarán en la cita --correspondiente al punto de entrada SIN_PARAMETROS [exception:] endSIN_PARAMETROS; ... acceptCON_PARAMETROS(A:in INTEGER;B:out FLOAT;C:in out BOOLEAN) do --conjunto de sentencias que se ejecutarán en la cita --correspondiente al punto de entrada CON_PARAMETROS endCON_PARAMETROS; endA;
Vista completa taskEJEMPLO is entry SIN_PARAMETROS; entryCON_PARAMETROS(A:in INTEGER;B:out FLOAT; C:in out BOOLEAN); endEJEMPLO; task bodyEJEMPLOis begin ... acceptSIN_PARAMETROSdo --conjunto de sentencias que se ejecutarán en la cita --correspondiente al punto de entrada SIN_PARAMETROS endSIN_PARAMETROS; ... acceptCON_PARAMETROS(A:in INTEGER;B:out FLOAT;C:in out BOOLEAN) do --conjunto de sentencias que se ejecutarán en la cita --correspondiente al punto de entrada CON_PARAMETROS endCON_PARAMETROS; ... endA;
Llamada a un punto de entrada • Se llama a un punto de entrada de la misma forma que a un procedimiento ... EJEMPLO.SIN_PARAMETROS; ... EJEMPLO.CON_PARAMETROS(a,b,c); ...
La cita o rendes-vous taskPEON is entry PREPARAR_MEZCLA(cantidad:in INTEGER); endPEON; task bodyPEONis begin loop --Peón haciendo otros trabajos ... acceptPREPARAR_MEZCLA(cantidad: in INTEGER) do --prepara la mezcla ... -mezcla preparada endPREPARAR_MEZCLA; end loop; endPEON; taskALBAÑIL; task bodyALBAÑILis cantidad: integer; begin loop --Trabajando ... PEON.PREPARAR_MEZCLA(cantidad); ... end loop; endALBAÑIL;
Atributo COUNT • El atributo E’COUNT da el número de tareas que están en un momento determinado en la cola del punto de entrada E • ¡ OJO al uso del atributo COUNT en las guardas ! • Da el número de tareas encoladas en el momento en que la guarda se evalúa, y este puede cambiar antes de que se acepte la cita
Temporización • delay segundos; • Suspende la tarea al menos “segundos” segundos • Si segundos<=0, no tiene efecto • segundos: Tipo Duration (coma fija) • Rango de valores • Depende de la implementación • Garantizan: • Precisión (Duration’small): no por encima de 20 milisegundos • Rango: al menos –86_400.0 a 86_400.0 (segundos de un día)
Temporización • delay until tiempo; • Tiempo: Tipo Time • Fecha • Hora (segundos transcurridos desde la media noche) • Más operaciones: • paquete Ada.Calendar • paquete Ada.Real_Time
Ada.Calendar package Ada.Calendar is type Time isprivate; subtype Year_Number is integer range 1901..2099; subtype Month_Number is integer range 1..12; subtype Day_Number is integer range 1..31; subtype Day_Duration is duration range 0.0..86_400.0; function Clock return Time; function Year(Date:Time) return Year_Number; function Month(Date:Time) return Month_Number; function Day(Date:Time) return Day_Number; function Second(Date:Time) return Day_Duration; procedure Split(Date: in Time; Year: out Year_Number; Month: out Month_Number; Day: out Day_Number; Seconds: out Day_Duration);
Ada.Calendar function Time_Of(Year: Year_Number; Month: Month_Number; Day: Day_Number; Seconds: Day_Duration) return Time; function “+”(Left: Time;Right: Duration) return Time; function “+”(Left: Duration; Right: Time) return Time; function “-”(Left: Time;Right: Duration) return Time; function “-”(Left: Time; Right: Time) return Duration; funciton “<“(Left,Right: Time) return Boolean; function “<=“(Left,Right: Time) return Boolean; function “>“(Left,Right: Time) return Boolean; function “>=“(Left,Right: Time) return Boolean; Time_Error: exception; private --implementation dependent end Ada.Calendar;
Sentencia Select select accept A(X: out item) do --sentencias end; --más sentencias or accept B(X:in item) do --sentencias end; --más sentencias or ... end select;
Sentencia Select (con guardas) • OJO! No es seguro que una guarda esté todavía a cierto cuando se realice la cita correspondiente • Si todas las guardas son falsas se eleva la excepción PROGRAM_ERROR • Si una guarda no existe se considera como cierta select when condicion => accept A(X: out item) do --sentencias end; --más sentencias or when condicion => accept B(X:in item) do --sentencias end; --más sentencias or ... end select;
Sentencia Select(con delay) select [when condicion =>] accept A(X: out item) do --sentencias end; --más sentencias or ... or ... or [when condicion =>] delay 10*MINUTOS; end select;
Sentencia Select(con else) • Una sentencia select no puede tener una rama else y otra delay (aunque la rama else si puede empezar con una sentencia delay) • Las sentencias accept pueden ir guardadas salvo la rama else select [when condicion =>] accept A(X: out item) do --sentencias end; --más sentencias or ... or ... else --sentencias end select;
Llamada temporizada • La sentencia select sólo puede tener una llamada a un punto de entrada y sin guarda select Peon.Preparar_Mezcla(cantidad); or delay 1*MINUTE; --HAGO OTRAS COSAS Y ME OLVIDO --DE LA MEZCLA end select;
Llamada condicional • La sentencia select sólo puede tener una llamada a un punto de entrada y sin guarda select Peon.Preparar_Mezcla(cantidad); else --HAGO OTRAS COSAS Y ME OLVIDO --DE LA MEZCLA end select;
Tipos Tarea procedureprincipalis task type T is --especificación entryE(...); end T; task body T is --cuerpo end T; X:T; vector: array(1..10) of T; type REC is record CT:T; ... end record; Y:REC; type REF_T isaccess T; RX: REF_T; --otras declaraciones begin X.E(...); vector(I).E(...); Y.CT.E(...); RX=new T; RX.E(...); endprincipal;
Dependencia y terminación • Una unidad no puede acabar hasta que todas las tareas dependientes de ella hayan terminado • Toda tarea depende de una unidad • Bloque, subprograma o cuerpo de tarea que la engloba y dentro del cual se declara, salvo: • Declaración de tareas en paquetes • Tareas creadas con el operador new
Dependencia • Declaración de tareas en paquetes • Dependerán del bloque, subprograma o cuerpo de tarea donde se declare el paquete • Tareas creadas con el operador new • Dependerán del bloque, subprograma o cuerpo de tarea donde se declaró el tipo acceso
Terminación • ¿ Cuándo termina la tarea “progenitora” ? • Select con alternativa terminate task type progenitora; task body progenitora is task type T; task body T is loop --cuerpo end loop; endT; tarea:T; begin ... endprogenitora;
Terminación • Se toma la alternativa terminate si la unidad de la que la tarea depende ha llegado al final, y por tanto, está completada • y además todas las tareas hermanas y tareas dependientes han terminado o pueden análogamente seleccionar una alternativa terminate • Puede estar guardada, pero no puede aparecer en una sentencia select que tenga una alternativa delay o else select ... or ... or terminate; end select;
Terminación • La selección de una sentencia alternativa terminate se entiende como una terminación normal • La tarea controla la situación y termina voluntariamente • La sentencia abort termina una o más tareas incondicionalmente
Terminación • Si se aborta una tarea, entonces todas las tareas que dependen de ella, o de un subprograma o bloque llamados en ese momento por ella, se abortan también
Terminación • Situaciones • Tarea suspendida • No suspendida • Caso especial: Se intenta abortar una tarea durante una cita • tarea llamada -> TASKING_ERROR • tarea llamante -> se completa la cita (la tarea permanece en un estado “anormal” y solo cuando se completa la cita, la tarea se completa debidamente)
Estado de una tarea • T’TERMINATED • Cierto si T ha terminado • T’CALLABLE • Cierto a menos que la tarea se haya completado o terminado o se encuentre en un estado “anormal” pendiente de que la aborten
TASKING_ERROR • Error durante la activación de alguna tarea • TASKING _ERRROR en la unidad progenitora • Aborta una tarea llamada durante una cita • TASKING_ERROR en la tarea llamante • Tareas encoladas en puntos de entrada de una tarea servidora que es abortada • TASKING_ERROR en las tareas encoladas
Otras situaciones de error • Si se produce una excepción durante una cita en la tarea llamada y no se maneja dicha excepción en el accept correspondiente, se propaga la excepción en ambas tareas • Si una tarea no maneja una excepción de ninguna manera, se abandona la tarea y se pierde la excepción
Objetos protegidos protected[type] OBJETOis function XXX(params) return tipo; procedure YYY(params); entry ZZZ(params); private --datos privados --otras funciones, procedimientos y --puntos de entrada privados end OBJETO; protected body OBJETO is --cuerpo (implementación) --A diferencia de los paquetes y tareas --en esta parte no se pueden declarar --datos endOBJETO;
Discriminantes protectedtype OBJETO(tamaño:integer:=100)is ... end OBJETO; protected body OBJETO is ... endOBJETO; tasktype T(tamaño:integer:=100)is ... end T; task body T is ... endT;
Objetos protegidos (OP) • Los objetos protegidos garantizan exclusión mutua en las diferentes llamadas a sus operaciones protegidas (funciones, procedimientos, puntos de entrada) • Funciones: sólo tienen permiso de lectura sobre los datos privados • Acceso concurrente a un objeto protegido
Operaciones protegidas protected body OBJETO is procedure YYY(...) is --declaraciones begin ... end YYY; function XXX return tipo; begin ... end XXX; entry ZZZ(...) when condicion is begin ... end ZZZ; endOBJETO;
Acceso a objetos protegidos Tareas esperando fuera del OP Tareas esperando en las barreras asociadas a los puntos de entrada Una tarea dentro del OP entry 1 . . . entry N
Condiciones barrera • Uso del atributo COUNT • + Llamadas temporizadas y condicionales • Tareas • Problemas: puede ocurrir que entre la evaluación de la condición y la cita, la condición haya cambiado • Objetos protegidos: • No es posible estas situaciones erróneas • La operación de quitar una tarea de una cola es una operación protegida. Por tanto, esto provocará que se reevalúen las condiciones
Requeue • requeue [punto de entrada]; • Encola una tarea en un punto de entrada de • la misma tarea • otra tarea • un objeto protegido • Pasa implícitamente los parámetros de la llamada original • No pueden pasarse parámetros explícitamente • No se puede abortar a una tarea que realice un operación requeue, salvo • requeue [punto de entrada] [with abort]
Ejemplo protectedEventis entry wait; entry signal; private entry reset; Ocurred:boolean:=False; end Event; protected body Event is entry wait when Ocurred is begin null; end wait; entry signal when True is begin if wait’count>0 then Ocurred:=True; Requeue reset; end if; end signal; entry reset when wait’count=0 is begin Ocurred:=False; end reset; end Event;