Anda di halaman 1dari 19

Programación Concurrente 2018

Explicación práctica ADA

Facultad de Informática
UNLP
El lenguaje ADA

 Desarrollado por el Departamento de Defensa de EEUU para que sea el


estándar en programación de aplicaciones de defensa (desde sistemas de
Tiempo Real a grandes sistemas de información).

 Desde el punto de vista de la concurrencia, un programa Ada tiene tasks


(tareas) que se pueden ejecutar independientemente y contienen
primitivas de sincronización.

 Los puntos de invocación (entrada) a una tarea se denominan entrys y


están especificados en la parte visible (encabezado de la tarea).

 Una tarea puede decidir si acepta la comunicación con otro proceso,


mediante la primitiva accept.

2
Tasks

 La forma más común de especificación de task es:


TASK nombre IS
declaraciones de ENTRYs
end;

 La forma más común de cuerpo de task es:


TASK BODY nombre IS
declaraciones locales
BEGIN
sentencias
END nombre;

 Una especificación de TASK define una única tarea → Una instancia


del correspondiente task body se crea en el bloque en el cual se
declara el TASK.
 Cuando se necesita más de una instancia, se debe declarar un tipo
TASK 3
Tasks

TASK nombre1 IS TASK TYPE nombre2 IS


declaraciones de ENTRYs declaraciones de ENTRYs
end; end;

TASK BODY nombre1 IS TASK BODY nombre2 IS


declaraciones locales declaraciones locales
BEGIN BEGIN
sentencias sentencias
END nombre; END nombre;

tareas: array(1..N) of nombre2

4
Sincronización
Entry
 El rendezvous es el principal mecanismo de sincronización en Ada y
también es el mecanismo de comunicación primario.
 Entry:
• Declaración de entry simples y familia de entry (parámetros IN, OUT y IN OUT).

TASK nombre IS
ENTRY e1;
ENTRY e2 (p1: IN integer; p2: OUT char; p3: IN OUT float);
end;

Los entry’s funcionan de manera semejante a los procedimientos: solo pueden recibir
o enviar información por medio de los parámetros del entry. No retornan valores
como las funciones.

5
Sincronización
Call: Entry Call
 Opciones para Entry Call:
• Entry call. La ejecución demora al llamador hasta que la operación termine (o
aborte o alcance una excepción).
• Entry call condicional (SELECT-ELSE) :
select entry call;
sentencias adicionales;
else
sentencias;
end select;

• Entry call temporal (SELECT-OR DELAY):


select entry call;
sentencias adicionales;
or delay tiempo
sentencias;
end select;

6
Sincronización
Sentencia de Entrada: Accept
 La tarea que declara un entry sirve llamados al entry con accept:
accept nombre (parámetros formales) do
sentencias
end nombre;

 Demora la tarea hasta que haya una invocación, copia los parámetros
reales en los parámetros formales, y ejecuta las sentencias. Cuando
termina, los parámetros formales de salida son copiados a los parámetros
reales. Luego ambos procesos continúan.

 Cada entry puede tener más de un call pendiente → cola

 Ejemplo:
accept e2 (p1: IN integer; p2: OUT char; p3: IN OUT float) do
sentencias
end e2;
7
Sincronización
Sentencia de Entrada: Accept
 Es posible que una tarea tenga pendiente más de un entry call diferente

 La sentencia wait selectiva soporta comunicación guardada.


select when B1  accept E1; sentencias1
or ...
or when Bn  accept En; sentenciasn
end select;

• Cada línea se llama alternativa. Las cláusulas when son opcionales.


• Puede contener una alternativa else, or delay.
• Uso de atributos del entry: count.

En los SELECT no es posible mezclar llamados con accept’s

8
Ejemplo
Atención en un banco

Modele la atención de un banco con un único empleado. Los clientes llegan y


son atendidos de acuerdo al orden de llegada.

9
Ejemplo
Atención en un banco

Procedure Banco is
TASK Body Empleado IS
TASK Type Cliente; Begin
loop
TASK Type Empleado IS Accept atención () do
entry atencion (); -- atender
end Empleado; End atención
End loop;
End Empleado;
emp: Empleado;
clientes: array (1..C) of Cliente; Begin
Null;
End Banco
TASK Body Cliente IS
Begin
Emp.atencion(); -- Pedir atención
End Cliente;

10
Ejemplo
Atención en un banco

Procedure Banco is
TASK Body Empleado IS
TASK Type Cliente; Begin
loop
TASK Type Empleado IS Accept atención () do
entry atencion (); -- atender
end Empleado; End atención
End loop;
End Empleado;
emp: Empleado;
clientes: array (1..C) of Cliente; Begin
Null;
End Banco
TASK Body Cliente IS
Begin
Emp.atencion(); -- Pedir atención
End Cliente;

Si los clientes esperan a lo sumo 10


minutos para ser atendidos, ¿qué
modificaciones debería hacer?

11
Ejemplo
Atención en un banco

Procedure Banco is
TASK Body Empleado IS
TASK Type Cliente; Begin
loop
TASK Type Empleado IS Accept atención () do
entry atencion (); -- atender
end Empleado; End atención
End loop;
End Empleado;
emp: Empleado;
clientes: array (1..C) of Cliente; Begin
Null;
End Banco
TASK Body Cliente IS
Begin
SELECT
Emp.atencion(); -- Pedir atención
OR DELAY (10*60)
-- retirarse;
Null;
End SELECT;
End Cliente;

12
Ejemplo
Atención en un banco

Procedure Banco is
TASK Body Empleado IS
TASK Type Cliente; Begin
loop
TASK Type Empleado IS Accept atención () do
entry atencion (); -- atender
end Empleado; End atención
End loop;
End Empleado;
emp: Empleado;
clientes: array (1..C) of Cliente; Begin
Null;
End Banco
TASK Body Cliente IS
Begin
SELECT
Emp.atencion(); -- Pedir atención
OR DELAY (10*60)
-- retirarse; Si los clientes no son atendidos
Null; inmediatamente, entonces se retiran.
End SELECT; ¿Qué modificaciones debería hacer?
End Cliente;

13
Ejemplo
Atención en un banco

Procedure Banco is
TASK Body Empleado IS
TASK Type Cliente; Begin
loop
TASK Type Empleado IS Accept atención () do
entry atencion (); -- atender
end Empleado; End atención
End loop;
End Empleado;
emp: Empleado;
clientes: array (1..C) of Cliente; Begin
Null;
End Banco
TASK Body Cliente IS
Begin
SELECT
Emp.atencion(); -- Pedir atención
ELSE
-- retirarse;
Null;
End SELECT;
End Cliente;

14
Ejemplo
Atención en un banco

Procedure Banco is
TASK Body Empleado IS
TASK Type Cliente; Begin
loop
TASK Type Empleado IS Accept atención () do
entry atencion (); -- atender
end Empleado; End atención
End loop;
End Empleado;
emp: Empleado;
clientes: array (1..C) of Cliente; Begin
Null;
End Banco
TASK Body Cliente IS
Begin
SELECT
Emp.atencion(); -- Pedir atención
ELSE
-- retirarse; Si ahora hay 2 tipos de clientes
Null; (regular y prioritario). ¿Qué
End SELECT; modificaciones debería hacer?
End Cliente;

15
Ejemplo
Atención en un banco

Procedure Banco is TASK Body ClientePrioritario IS


Begin
TASK Type Cliente;
Emp.atencionPrioritaria(); -- Pedir atención
TASK Type ClienteProritario; End Cliente;

TASK Type Empleado IS


entry atencion (); TASK Body Empleado IS
Begin
entry atencionPrioritaria (); loop
end Empleado; SELECT
When (atencionPrioritaria’count == 0) =>
emp: Empleado; Accept atención () do
-- atender
clientes: array (1..C) of Cliente;
End atención
clientesP: array (1..C) of ClientePrioritario; OR
Accept atenciónPrioritaria () do
TASK Body Cliente IS -- atender
Begin End atención
End SELECT;
Emp.atencion(); -- Pedir atención End loop;
End Cliente; End Empleado;

Begin
Null;
End Banco

16
Ejemplo
Atención en un banco

Procedure Banco is TASK Body ClientePrioritario IS


Begin
TASK Type Cliente;
Emp.atencionPrioritaria(); -- Pedir atención
TASK Type ClienteProritario; End Cliente;

TASK Type Empleado IS


entry atencion (); TASK Body Empleado IS
Begin
entry atencionPrioritaria (); loop
end Empleado; SELECT
When (atencionPrioritaria’count == 0) =>
emp: Empleado; Accept atención () do
-- atender
clientes: array (1..C) of Cliente;
End atención
clientesP: array (1..C) of ClientePrioritario; OR
Accept atenciónPrioritaria () do
TASK Body Cliente IS -- atender
Begin Considere End atención
la situación en que el
End SELECT;
Emp.atencion(); -- Pedir atención cliente
Endle pasa su ID al empleado y
loop;
End Cliente; ésteEnd
le retorna
Empleado; un número de trámite
por Begin
cualquier reclamo futuro. ¿Qué
modificaciones
Null; debería hacer?
End Banco

17
Ejemplo
Atención en un banco

Procedure Banco is TASK Body Cliente IS


TASK Type Cliente IS miId, miTramite: int;
identificación (id: IN int); Begin
End Cliente; Accept identificación (id: IN int) do
miId := id;
TASK Type ClienteProritario IS end identificación;
identificación (id: IN int); Emp.atencion(miId,miTramite); -- Pedir atención
End ClientePrioritario; End Cliente;

TASK Type Empleado IS TASK Body ClientePrioritario IS


entry atencion (id: IN int; nroTramite: OUT int); miId, miTramite: int;
entry atencionPrioritaria (id: IN int; nroTramite: Begin
OUT int); Accept identificación (id: IN int) do
end Empleado; miId := id;
end identificación;
emp: Empleado; Emp.atencionPrioritaria(miId,miTramite); -- Pedir
atención
clientes: array (1..C) of Cliente; End Cliente;
clientesP: array (1..C) of ClientePrioritario;

18
Ejemplo
Atención en un banco

TASK Body Empleado IS


Begin
loop
SELECT
When (atencionPrioritaria’count == 0) =>
Accept atención (id: IN int; nroTramite: OUT int) do
-- atender
nroTramite := algun_valor;
End atención
OR
Accept atenciónPrioritaria (id: IN int ; nroTramite: OUT int) do
-- atender
nroTramite := algun_valor;
End atención
End SELECT;
End loop;
End Empleado;

Begin
for i in 1..C loop
Cliente(i).identificacion(i);
ClientePrioritario(i).identificacion(i);
end loop;
End Banco

19