3

具体的には、タスクが自身への参照を取得する方法はありますか?

例えば:

task type someTask; 
type someTaskAccessor is access someTask;

task body someTask is
    pointerToTask : someTaskAccessor;
begin
    pointerToTask = this;
end someTask;
4

5 に答える 5

5

私が提案できる最も明白な解決策は、作成したばかりのタスクへの参照を渡すランデブー (エントリ) をタスクの最初に宣言することです。もう 1 つの可能性は、タスク タイプに判別式を使用することです。その役割は、新しいタスクにその配置場所を伝えることです (新しいタスクへのアクセスを判別式に渡します)。残念ながら、私は Ada コンパイラを手元に持っていないので、実際の例を示すことはできません。

とにかく、あなたのコメントに基づいて:新しいタスクの作成はどこかで処理する必要があります。その時点で、この新しいタスクが二重リンクリストのどこに入るかを決定する必要もあります(少なくとも1つの既存のタスクを知る必要があります彼らが通信するために新しいものを作成するとき: 彼らは魔法のように自分自身を発見しません)。新しく作成されたタスクとその左と右のピアがあるこの瞬間を利用して、誰が隣人であるかを全員に伝えることができます (もう一度ランデブーを使用します)。

于 2009-11-01T22:43:59.447 に答える
4

パッケージAda.Task_Identificationは、現在のタスクの Task_ID を取得するための Current_Task 関数を提供します。

于 2009-10-31T21:03:04.920 に答える
1

ここにいくつかのことがあります。

まず、AdaはC++とは異なる方法でOOを実行します。この言語には「this」ポインタはありません。ディスパッチはパラメータから行われます。これの1つの意味は、C ++とは異なり、複数のパラメーターからディスパッチすることが可能であるということです。しかし、それはまた別の議論です。気に入らない場合は、いつでもディスパッチパラメータに「this」という名前を付けることができます。

第二に、OOの概念は、タスクのような並行性オブジェクトにはあまりうまく適用されません。これはエイダのせいではありません。これはよく知られている問題です。悲しいことに、それはかなり想像を絶する「並行性の問題」と呼ばれていたので、それへの参照はグーグル検索でのプログラミングの問題でいっぱいになります。基本的な要点は、オブジェクトに継承や動的ディスパッチなどの優れた機能をサポートさせることも、並行性をサポートさせることもできるということです。同じ言語構造で両方を行うことは非常に困難です。

実用性の問題として、独自のタスクへのポインターが必要な場合は、それをグローバルにするか、それを割り当てるタスクに、ある種の初期化ランデブーを使用してポインターを渡すようにすることができます。これが以前に行われたのを見たことがあります。ワーカータスクのスタック内のタスクが、終了時に「アイドル」スタックに戻されるようにするためです。

于 2009-11-12T15:36:29.123 に答える
0

私があなただったら、あなたのコードを再編成します。そのため、他のタスクと相互作用するいくつかのタスクがあり、現在は 2 つのタスクがあります。また、タスクを保存し、タスクの挿入/削除を管理するリンクされたリストがあります。これは、同期を処理する必要があるグローバル オブジェクトです。

そのため、保護されたオブジェクトを作成し、その中にタスクのリストを保存することをお勧めします。protected は通常、一部のリソースを同期して処理する必要があるパッシブ オブジェクトに使用されます。挿入、削除などの手順を使用できます。これにより、一度に 1 つの作成と削除のみが実行され、リンクされたリストに矛盾が生じなくなります。

各タスクは、タスクの挿入または削除時に変更される可能性のある「パートナー」タスクであることを認識している必要があります。隣人を更新するタスクへのエントリを作成することをお勧めします。タスクが出入りするとき、保護されたオブジェクトは隣接オブジェクトを更新します。

この場合、保護されたオブジェクトがすべてを整理するため、「this」ポインターにアクセスする必要はありません。タスクを識別できる ID のみが必要です (削除用)。

コードを書き込もうとしましたが、現在コンパイラがありません:

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;
于 2009-11-11T14:32:09.260 に答える