Domanda

In particolare, c'è un modo per un compito per ottenere un riferimento a se stesso?

Ad esempio:

task type someTask; 
type someTaskAccessor is access someTask;

task body someTask is
    pointerToTask : someTaskAccessor;
begin
    pointerToTask = this;
end someTask;
È stato utile?

Soluzione

la soluzione più evidente potrei suggerire è quello di dichiarare un rendez-vous (una voce), proprio all'inizio del vostro compito, a cui si passa un riferimento al compito appena creato. L'altra possibilità è usando una discriminante per il vostro tipo di attività, il cui ruolo è quello di raccontare una nuova attività in cui si trova (passare l'accesso al nuovo compito in discriminante). purtroppo, non ho un compilatore Ada a portata di mano in modo che io non posso dare alcun esempio di lavoro.

In ogni caso, in base al commento: la creazione di una nuova attività deve essere gestita da qualche parte, a quel punto si dovrà anche determinare dove questo nuovo compito verrà inserito nella tua lista doppiamente collegata (è necessario conoscere almeno un compito esistente durante la creazione di un nuovo in modo per loro di comunicare: non sarà scoprire se stessi magicamente). si può approfittare di questo momento, quando si ha il compito appena creata e dei suoi pari a destra ea sinistra, per dire a tutti che sono loro vicino di casa (con un rendez-vous, ancora una volta).

Altri suggerimenti

Il pacchetto Ada.Task_Identification fornisce la funzione per recuperare Current_Task Task_ID della attività corrente.

Un paio di cose qui.

Prima di tutto, Ada fa OO in modo diverso che il C ++. Non ci sono "questo" puntatori nel linguaggio. Dispacciamento è fatto fuori di parametri. Una conseguenza di questo è che è possibile inviare fuori di più di un parametro, a differenza di C ++. Questa è un'altra discussione per un'altra volta però. Se non ti piace, si può sempre chiamare il vostro parametro di dispacciamento "questo".

In secondo luogo, concetti OO in realtà non si applicano molto bene agli oggetti di concorrenza come compiti. Questo non è colpa di Ada. Si tratta di un problema ben noto. Purtroppo, è stato piuttosto unimaginatively definito "Il Concurrency problema", quindi i riferimenti ad esso ottenere inondato con problemi di programmazione su una ricerca su Google. La sostanza di base è che si può rendere gli oggetti supportano ereditarietà e la spedizione dinamica e tutta quella roba buona, oppure si può fare li supportano la concorrenza. Facendo entrambi nella stessa struttura del linguaggio è molto difficile.

Come una questione di praticità, se avete bisogno di un puntatore al proprio compito, è possibile rendere un globale, o che hanno il compito che assegna passare il puntatore utilizzando qualche tipo di initilization appuntamento. Ho visto questo fatto prima, di avere un compito in una pila di compiti dei lavoratori si è messa di nuovo in pila "idle" quando finisce.

Anche se questo argomento è vecchio mi sono imbattuto in essa alla ricerca di qualcosa di simile me stesso (il mio bisogno stava permettendo un compito di passare un manico a se stesso per un'area della mappa di memorizzazione di hash protetta che tutte le attività hanno accesso, in incidere una registrazione) .

È possibile farlo in Ada 2005, pensato non è raccomandato perché disabilita i controlli di accesso, ma è l'unico modo che ho trovato per avere un compito di generare (o trovare) di essa la propria maniglia di passare in funzioni di richiamata (si prega di notare questo non esclude Task_ID passando per verificare la presenza di terminazione 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;

Vorrei riorganizzare il codice, se fossi in te. Quindi, ci sono alcuni compiti che interagiscono con altri compiti, ora con 2 compiti. E c'è legata lista, che è responsabile per la conservazione dei compiti e gestire l'inserzione / delezione di compiti. Si tratta di un oggetto globale che dovrebbe maniglia sincronizzato.

Ecco perché vi consiglio di creare un oggetto protetto, e memorizzare l'elenco delle attività all'interno di questo. Il protetto viene in genere utilizzato per oggetti passivi, in cui alcuni risorsa deve essere maniglia sincronizzato. Si può avere procedure come inserto, rimuovere ecc Questo farà sì che solo una creazione e la rimozione sarà in esecuzione in un momento, e la lista collegata non sarà incoerente.

Ogni attività deve sapere che è "partner" compiti che possono cambiare quando l'inserimento o la rimozione di un compito. I consigli del creare una voce nel compito che aggiornerà i suoi vicini. Quando le attività vengono o lasciare, l'oggetto protetto aggiornerà i vicini di casa.

In questo caso, non c'è bisogno di accedere al puntatore "this", perché l'oggetto protetto organizzerà tutto. Solo è necessario un ID, che può identificare il compito (per la rimozione).

I provare a scrivere il codice, ma non ho compilatore ora:

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;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top