Introducción
En Ada, los objetos protegidos son una característica avanzada que permite la sincronización y la comunicación segura entre tareas concurrentes. Los objetos protegidos proporcionan un mecanismo para garantizar que las operaciones críticas se realicen de manera atómica, evitando condiciones de carrera y otros problemas de concurrencia.
Conceptos Clave
- Objeto Protegido: Una estructura que encapsula datos y operaciones, garantizando que las operaciones se realicen de manera segura en un entorno concurrente.
- Operaciones Protegidas: Métodos definidos dentro de un objeto protegido que pueden ser llamados por tareas concurrentes.
- Entrada Protegida: Un tipo especial de operación protegida que puede ser bloqueada hasta que se cumpla una condición específica.
- Exclusión Mutua: Garantiza que solo una tarea puede ejecutar una operación protegida a la vez.
Definición de un Objeto Protegido
Un objeto protegido se define utilizando la palabra clave protected. Aquí hay un ejemplo básico:
protected type Shared_Counter is
procedure Increment;
function Value return Integer;
private
Counter : Integer := 0;
end Shared_Counter;
protected body Shared_Counter is
procedure Increment is
begin
Counter := Counter + 1;
end Increment;
function Value return Integer is
begin
return Counter;
end Value;
end Shared_Counter;Explicación del Código
- Declaración del Tipo Protegido:
protected type Shared_Counter isdefine un tipo protegido llamadoShared_Counter. - Operaciones Protegidas:
procedure Incrementyfunction Value return Integerson las operaciones protegidas que pueden ser llamadas por tareas concurrentes. - Sección Privada:
privatedefine la sección donde se declaran los datos internos del objeto protegido. En este caso,Counteres una variable entera que se inicializa a 0. - Cuerpo del Objeto Protegido:
protected body Shared_Counter isdefine la implementación de las operaciones protegidas.
Uso de Objetos Protegidos
Para utilizar un objeto protegido, primero se debe declarar una instancia del tipo protegido y luego llamar a sus operaciones:
declare
My_Counter : Shared_Counter;
begin
My_Counter.Increment;
Put_Line("Counter Value: " & Integer'Image(My_Counter.Value));
end;Explicación del Código
- Declaración de la Instancia:
My_Counter : Shared_Counterdeclara una instancia del tipo protegidoShared_Counter. - Llamada a Operaciones Protegidas:
My_Counter.Incrementincrementa el contador yMy_Counter.Valueobtiene el valor actual del contador.
Ejemplo Práctico
Vamos a crear un ejemplo más complejo donde varias tareas incrementan un contador protegido:
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure Main is
protected type Shared_Counter is
procedure Increment;
function Value return Integer;
private
Counter : Integer := 0;
end Shared_Counter;
protected body Shared_Counter is
procedure Increment is
begin
Counter := Counter + 1;
end Increment;
function Value return Integer is
begin
return Counter;
end Value;
end Shared_Counter;
My_Counter : Shared_Counter;
task type Worker is
end Worker;
task body Worker is
begin
for I in 1 .. 100 loop
My_Counter.Increment;
end loop;
end Worker;
Workers : array (1 .. 10) of Worker;
begin
delay 1.0; -- Esperar a que todas las tareas terminen
Put_Line("Final Counter Value: " & Integer'Image(My_Counter.Value));
end Main;Explicación del Código
- Declaración del Tipo Protegido: Igual que antes, se define
Shared_Countercon operacionesIncrementyValue. - Declaración de la Instancia:
My_Counter : Shared_Counterdeclara una instancia del tipo protegido. - Tarea
Worker: Se define una tarea que incrementa el contador 100 veces. - Array de Tareas:
Workers : array (1 .. 10) of Workerdeclara un array de 10 tareasWorker. - Sincronización:
delay 1.0espera un segundo para asegurarse de que todas las tareas hayan terminado antes de imprimir el valor final del contador.
Ejercicio Práctico
Ejercicio
Modifica el ejemplo anterior para que cada tarea Worker incremente el contador un número aleatorio de veces entre 1 y 100.
Solución
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Numerics.Float_Random;
procedure Main is
protected type Shared_Counter is
procedure Increment;
function Value return Integer;
private
Counter : Integer := 0;
end Shared_Counter;
protected body Shared_Counter is
procedure Increment is
begin
Counter := Counter + 1;
end Increment;
function Value return Integer is
begin
return Counter;
end Value;
end Shared_Counter;
My_Counter : Shared_Counter;
task type Worker is
end Worker;
task body Worker is
package Random is new Ada.Numerics.Float_Random;
Gen : Random.Generator;
Random_Value : Float;
Increment_Count : Integer;
begin
Random_Value := Random.Random(Gen);
Increment_Count := Integer(Random_Value * 100.0) + 1;
for I in 1 .. Increment_Count loop
My_Counter.Increment;
end loop;
end Worker;
Workers : array (1 .. 10) of Worker;
begin
delay 1.0; -- Esperar a que todas las tareas terminen
Put_Line("Final Counter Value: " & Integer'Image(My_Counter.Value));
end Main;Explicación del Código
- Generación de Números Aleatorios: Se utiliza el paquete
Ada.Numerics.Float_Randompara generar un número aleatorio entre 0 y 1. - Cálculo del Número de Incrementos:
Increment_Count := Integer(Random_Value * 100.0) + 1convierte el valor aleatorio en un número entero entre 1 y 100. - Bucle de Incremento:
for I in 1 .. Increment_Count loopincrementa el contador el número aleatorio de veces.
Conclusión
En esta sección, hemos aprendido sobre los objetos protegidos en Ada, cómo definirlos y utilizarlos para sincronizar tareas concurrentes. Los objetos protegidos son una herramienta poderosa para garantizar la seguridad y la integridad de los datos en aplicaciones concurrentes. En la próxima sección, exploraremos los sistemas en tiempo real y cómo Ada maneja la concurrencia en estos entornos.
Curso de Programación en Ada
Módulo 1: Introducción a Ada
Módulo 2: Conceptos Básicos
- Variables y Tipos de Datos
- Operadores y Expresiones
- Estructuras de Control
- Bucles en Ada
- Subprogramas: Procedimientos y Funciones
Módulo 3: Tipos de Datos Avanzados
Módulo 4: Programación Modular
Módulo 5: Concurrencia y Programación en Tiempo Real
Módulo 6: Temas Avanzados
Módulo 7: Mejores Prácticas y Optimización
- Estilo de Código y Mejores Prácticas
- Depuración y Pruebas
- Optimización del Rendimiento
- Consideraciones de Seguridad
