Frage

Im Einzelnen gibt es eine Möglichkeit für eine Aufgabe, eine Referenz auf sich selbst zu bekommen?

Zum Beispiel:

task type someTask; 
type someTaskAccessor is access someTask;

task body someTask is
    pointerToTask : someTaskAccessor;
begin
    pointerToTask = this;
end someTask;
War es hilfreich?

Lösung

das offensichtlichste Lösung, die ich vorschlagen könnte, ist ein Rendez-vous (einen Eintrag) ganz am Anfang Ihrer Aufgabe zu erklären, zu der Sie einen Verweis auf die Aufgabe passieren gerade erstellt haben. Die andere Möglichkeit ist eine Diskriminante zu Ihrem Aufgabentyp verwendet wird, deren Aufgabe es ist, eine neue Aufgabe zu sagen, wo es sich befindet (die Zugriff auf die neue Aufgabe in die Diskriminante passieren). Leider habe ich keine Ada-Compiler zur Hand haben, so kann ich Ihnen keine Arbeitsbeispiel geben kann.

Wie auch immer, basierend auf Ihren Kommentar: die Schaffung einer neuen Aufgabe muss irgendwo behandelt werden, an welcher Stelle Sie werden auch feststellen müssen, wo diese neue Aufgabe in die doppelt verknüpfte Liste gehen (Sie müssen zumindest wissen eine bestehende Aufgabe, wenn eine neue, um für sie zu schaffen kommunizieren: sie werden sich nicht entdecken magisch). Sie können die Vorteile dieser Moment Zeit nehmen, wenn Sie die neu erstellte Aufgabe und ihre linken und rechten Peers haben, jeder zu sagen, wer ihre Nachbarn (unter Verwendung eines Rendez-vous wieder einmal).

sind

Andere Tipps

Das Paket Ada.Task_Identification bietet die Current_Task Funktion der aktuellen Aufgabe des Task_ID.

abrufen

Ein paar Dinge hier.

Zunächst einmal, Ada tut OO anders, dass C ++. Es gibt keine „diese“ Zeiger in der Sprache. Dispatching wird aus den Parametern. Eine Folge davon ist, dass es möglich ist, aus der mehr als ein Parameter zu versenden, anders als in C ++. Das ist eine andere Diskussion, obwohl eine andere Zeit. Wenn Sie es nicht mögen, können Sie immer Ihre Disposition Parameternamen „this“.

Zum anderen OO-Konzepte wirklich nicht gelten sehr gut in der Parallelität Objekten wie Aufgaben. Dies ist nicht Ada Schuld. Es ist ein bekanntes Problem. Leider war es eher einfallslos als „Das Concurrency Problem“, so Verweise auf sie mit Fragen zur Programmierung auf einer Google-Suche überschwemmt erhalten. Der grundlegende Kern ist, dass man Objekte inheritence unterstützen machen und dynamische Dispatch und alles, was gute Sachen, oder Sie können sie Gleichzeitigkeit unterstützen machen. beide in der gleichen Sprachstruktur zu tun, ist sehr schwierig.

Als eine Frage der Praktikabilität, wenn Sie einen Zeiger auf Ihre eigene Aufgabe benötigen, können Sie entweder machen es zu einem globalen, oder die Aufgabe haben, die es den Zeiger in Anwendung irgendeiner Art von initilization Rendezvous passieren zuordnet. Ich habe dies vorher getan gesehen, eine Aufgabe, die in einem Stapel von Arbeitern Aufgaben haben setzte sich auf den „Leerlauf“ Stapel zurück, wenn es fertig ist.

Auch wenn dieses Thema ist alt ich über sie lief die Suche nach etwas ähnlichem selbst (mein Bedürfnis, eine Aufgabe erlaubt einen Griff auf mich zu einem geschützten Hash-Kartenspeicherbereich zu passieren, dass alle Aufgaben Zugriff haben, im Affekt eine Registrierung) .

Sie können dies tun, in Ada 2005 gedacht ist es nicht zu empfehlen, da sie den Zugang Kontrollen deaktiviert, aber es ist der einzige Weg, die ich gefunden habe eine Aufgabe haben, erzeugen (oder finden) seinen eigenen Griff in Aufruf zurücklaufen Funktionen (bitte beachten dies schließt nicht aus, Task_ID für Kündigung oder is_callable überprüfen vorbei):

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;

Ich würde Ihr Code neu zu organisieren, wenn ich Sie wäre. So gibt es einige Aufgaben, die mit anderen Aufgaben in Wechselwirkung treten, jetzt mit 2 Aufgaben. Und es wird die Liste verknüpft, die für die Speicherung der Aufgaben zuständig ist und verwalten die Einfügen / Löschen von Aufgaben. Dies ist ein globales Objekt, das synchronisierte behandeln soll.

Deshalb habe ich rate Ihnen ein geschütztes Objekt zu erstellen, und speichern Sie die Liste der Aufgaben innerhalb dieses. Das geschützte wird typischerweise für passive Objekte verwendet, wo einige Ressourcen synchronisiert werden Griff muss. Sie können Verfahren wie Insert, entfernen Sie usw. Dadurch wird sichergestellt, dass nur eine Schöpfung und die Entfernung zu einem Zeitpunkt ausgeführt werden, und die verkettete Liste wird nicht im Widerspruch sein.

sollte Jede Aufgabe wissen, dass es „Partner“ Aufgaben, die beim Einsetzen oder Entfernen einer Aufgabe ändern könnten. Ich rate der einen Eintrag in die Aufgabe erstellen, die ihre Nachbarn aktualisieren. Wenn Aufgaben kommen oder verlassen, wird das geschützte Objekt, um die Nachbarn zu aktualisieren.

In diesem Fall keine Notwendigkeit, Zugriff auf den „diesen“ Zeiger, weil das geschützte Objekt alles organisieren. Nur eine ID benötigt wird, was die Aufgabe identifizieren kann (zur Entfernung).

Ich versuche, den Code zu schreiben, aber ich habe nicht Compiler jetzt:

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;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top