Programación en Ada/Tareas/Dinámicas

← Tareas/Llamadas a punto de entrada complejas Tareas dinámicas (tipos tarea) Tareas/Dependencia →


Creación dinámica de tareas (tipos tareas)

editar

Además de poder declarar tareas como un simple objeto, se pueden declarar un tipo como tipo tarea. Con ello se consigue poder utilizar otros objetos que utilicen dicho tipo tarea como por ejemplo, un vector de tareas o un puntero a tarea (con lo que se consigue crear tareas dinámicamente).

La sintaxis de los tipos tarea es la siguiente:

declaración_tipo_tarea ::=
  task type identificador [ ( discriminante { ; discriminante } ) ] [ is
    { punto_entrada_tarea | cláusula_representación }
  [ private { punto_entrada_tarea | cláusula_representación } ]
  end [ identificador ] ] ;
discriminante ::=
  identificador { , identificador } : [ access ] subtipo [ := expresión ]

Con ello, se define un nuevo tipo. Esta definición necesita una terminación, es decir, faltaría declarar el cuerpo de la tarea, que se realiza de igual manera que si se hubiera declarado la tarea simplemente.

Los tipos tarea son privados limitados. Es decir, un objeto declarado de tipo tarea no es una variable, se comporta como una constante. Por tanto, no se permite la asignación, igualdad y desigualdad para los tipos tarea.

Según la sintaxis descrita, se puede definir una tarea como un tipo, por ejemplo, de esta manera:

declare
  task type TTareaA;
  task type TTareaB;
  task type TTareasMúltiples;
  type TVectorTareas is array (1..10) of TTareasMúltiples;
  A: TTareaA;
  B: TTareaB;
  V: TVectorTareas;
  task body TTareaA is
    -- ...
  end;
  task body TTareaB is
    -- ...
  end;
  task body TTareasMúltiples is
    -- ...
  end;
begin  -- A partir de aquí se ejecutan las 12 tareas concurrentemente.
  -- ...
end;

En el momento en el que dé comienzo la ejecución del bloque, justo después de begin, dará comienzo la ejecución simultánea de las tareas definidas en las distintas variables del tipo task. En este caso TTareaA, TTareaB y 10 TTareasMúltiples. Pero esta situación es estática, no se pueden lanzar tareas en un determinado instante; para ello, se pueden emplear punteros como, por ejemplo:

procedure Ejemplo_tareas_dinámicas is
  task type TTarea;
  type PTTarea is access TTarea;
  T1: PTTarea;
  T2: PTTarea := new TTarea;  -- Se crea la tarea T2.all.
begin
  T1 := new TTarea;  -- Se crea la tarea T1.all.
  T1 := null;  -- Se pierde la referencia, pero se sigue ejecutando.
  -- ...
end Ejemplo_tareas_dinámicas;

Las tareas creadas con new siguen unas reglas de activación y dependencia ligeramente diferentes. Estas tareas inician su activación inmediatamente después de la evaluación del asignador de la sentencia new. Además, estas tareas no dependen de la unidad donde se crearon, sino que dependen del bloque, cuerpo de subprograma o cuerpo de tarea que contenga la declaración del tipo access en sí. Para referenciar a tareas dinámicas se emplea el nombre de la variable puntero seguido de .all, por ejemplo, T1.all. Si se quiere que termine una tarea creada dinámicamente se debe utilizar la sentencia abort. Por ejemplo, abort T1.all.

También se pueden crear varios ejemplares de un mismo tipo dependiendo de un parámetro denominado discriminante. Por ejemplo:

task type TManejadorTeclado (ID: TIDentifTeclado := IDPorDefecto) is
  entry Leer (C: out Character);
  entry Escribir (C: in  Character);
end TManejadorTeclado;
type PTManejadorTeclado is access TManejadorTeclado;
Terminal: PTManejadorTeclado := new TManejadorTeclado (104);

Manual de referencia de Ada

editar