Pregunta

En concreto, hay una manera para una tarea para obtener una referencia a sí mismo?

Por ejemplo:

task type someTask; 
type someTaskAccessor is access someTask;

task body someTask is
    pointerToTask : someTaskAccessor;
begin
    pointerToTask = this;
end someTask;
¿Fue útil?

Solución

la solución más evidente que podría sugerir es declarar un rendez-vous (una entrada) en el comienzo de su tarea, a la que se pasa una referencia a la tarea que acaba de crear. la otra posibilidad es usar un discriminante para el tipo de tarea, cuyo papel es el de contar una nueva tarea a la que pertenece (pasar el acceso a la nueva tarea en el discriminante). Por desgracia, no tengo un compilador de Ada a la mano, así que no puedo dar ningún ejemplo de trabajo.

De todas formas, en función de su comentario: la creación de una nueva tarea tiene que ser manejado en algún lugar, momento en el que también tendrá que determinar dónde esta nueva tarea voy a entrar en su lista doblemente enlazada (lo que necesita saber al menos una tarea existente al crear uno nuevo con el fin de que puedan comunicarse: no van a descubrirse a sí mismos mágicamente). usted puede tomar ventaja de este momento, cuando se tiene la tarea de nueva creación y sus compañeros de izquierda y derecha, para decirle a todo el mundo que están a su vecino (usando una cita una vez más).

Otros consejos

El paquete Ada.Task_Identification proporciona la función Current_Task para recuperar task_id de la tarea actual.

Un par de cosas aquí.

En primer lugar, Ada hace OO diferente que C ++. No hay "este" punteros en el lenguaje. El despacho se realiza fuera de los parámetros. Una implicación de esto es que es posible enviar fuera de más de un parámetro, a diferencia de en C ++. Esa es otra discusión para otro momento sin embargo. Si no te gusta, siempre se puede nombrar a su despacho parámetro "este".

En segundo lugar, los conceptos OO en realidad no se aplican muy bien a los objetos de concurrencia como tareas. Esto no es culpa de Ada. Es un problema bien conocido. Por desgracia, era bastante poco imaginativa denomina "El problema de concurrencia", por lo que las referencias a obtener inundado de problemas de programación en una búsqueda en Google. El punto básico es que se puede hacer que los objetos soportan sucesiones y despacho dinámico y todas esas cosas buenas, o puede hacer que el soporte de concurrencia. Hacer ambas cosas en la misma estructura de la lengua es muy difícil.

Como cuestión de practicidad, si necesita un puntero a su propia tarea, puede que sea un mundial, o tienen la tarea que asigna pasar el puntero en el uso de algún tipo de encuentro initilization. He visto este hecho antes, para tener una tarea en una pila de tareas de los trabajadores volver a colocarlo en la pila "inactivo" cuando se termine.

A pesar de que este tema es viejo me encontré con él en busca de algo similar a mí mismo (mi necesidad permitía una tarea para pasar un mango a sí mismo a un mapa de la zona de almacenamiento de hash protegida que todas las tareas tienen acceso a, en afectar a un registro) .

Usted puede hacer esto en Ada 2005, que se cree que no es recomendable, ya que desactiva las verificaciones de acceso pero es la única forma que he encontrado para tener una tarea de generar (o encontrar) su propio mango para pasar a funciones de retrollamada (tenga en cuenta esto no excluye task_id que pasa para comprobar Terminación o is_callable):

task type someTask; 
type someTaskAccessor is access someTask;

task body someTask is
   -- Initialize the access type variable as pointing to the same task it's declared in.
   pointerToTask : someTaskAccessor := someTask'Unchecked_Access; --equiv to "this" ptr
begin
 --  pointerToTask = this; --this is unneeded, pointerToTask is already set!
end someTask;

Me reorganizar su código si fuera tú. Por lo tanto, hay algunas tareas que interactúan con otras tareas, ahora con 2 tareas. Y hay lista, que se encarga de almacenar las tareas y gestionar la inserción / deleción de tareas relacionadas. Este es un objeto global que deben manipular sincronizada.

Es por eso que aconsejo que crear un objeto protegido, y almacenar la lista de tareas dentro de eso. El protegido se utiliza típicamente para objetos pasivos, donde algunos de los recursos debe ser maneta sincronizada. Puede tener procedimientos como insertar, eliminar, etc. Esto asegurará que sólo una creación y eliminación va a correr a la vez, y la lista enlazada no será inconsistente.

Cada tarea debe saber Es tareas "socio" que podría cambiar cuando la inserción o retirada de una tarea. Aconsejo al crear una entrada en la tarea que actualizará sus vecinos. Cuando las tareas entran o salen, el objeto protegido actualizará los vecinos.

En este caso, no hay necesidad de acceder al puntero "this", debido a que el objeto protegido organizará todo. Sólo se necesita un ID, que puede identificar la tarea (para la eliminación).

Trato de escribir el código, pero no tengo ahora compilador:

task type computer;
type computer_ptr is access all computer;    
task type computer is
 entry init(id:integer);
 entry set_neighbor(left,right:computer_ptr);
end computer;

protected comp_list is
 procedure insert; -- called by organizer
 procedure remove(from:integer); -- called by task
private
 type comp_list is array(integer range<>) of computer_ptr;
 comps:comp_list(1..MAX):=(others=>null); -- or use own structure
end comp_list;

task body computer is
 id_:integer;
 left_n,right_n:computer_ptr:=null;
begin
 accept init(id:integer) do
  id_:=id;
 end init;
 while true loop
  select
   accept set_neighbor(left,right:computer_ptr) do
    left_n:=left;right_n:=right;
   end set_neighbor;
   or
    -- do its work
  end select;
  if (some_condition) then
   comp_list.remove(id_);
   break;
  end if;
 end loop;
end task computer;

protected body comp_list is
 procedure insert is
  p:computer_ptr;
 begin
  p:=new computer;
  -- add to list -> nr;
  p.all.init(nr);
  -- call set_neighbor to its left and itself
 end insert;
 procedure remove(from: integer) is
 begin
  -- remove from list and get its neighbors
  -- call set_neighbor regarding new ones
 end remove;
end comp_list;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top