具体而言,是有任务的方式来获得对自身的引用?

例如:

task type someTask; 
type someTaskAccessor is access someTask;

task body someTask is
    pointerToTask : someTaskAccessor;
begin
    pointerToTask = this;
end someTask;
有帮助吗?

解决方案

最明显的解决方案,我可以建议是宣布你的任务一开始就相约(入口),到你传递给刚创建的任务的参考。另一种可能是使用判别你的任务类型,其作用是告诉一个新的任务所在(通过进入新的任务进入了判别)。不幸的是,我没有在手的Ada编译,所以我不能给你任何工作示例。

反正,根据您的评论:需要一个新的任务创建某处被处理,此时你还需要确定这个新的任务将进入您的双向链表(你需要知道的至少一个创造,以便他们沟通一个新的时现有的任务:他们不会发现自己神奇)。你可以利用这个机会的优势,当你有新创建的任务和它的左,右同行,告诉大家谁是他们的邻居(使用相约再次)。

其他提示

在包 Ada.Task_Identification 提供Current_Task函数来检索当前任务的TASK_ID。

一个几件事情在这里。

首先,阿达确实OO不同的是C ++。有没有“这个”指针的语言。调度被关闭的参数来实现。这方面的一个含义是,有可能派遣过一个以上的参数,不像C ++。这是另一次虽然另议。如果你不喜欢它,你总是可以命名调度参数“这个”。

其次,面向对象的概念并不真正适用很好地象任务并发对象。这是不是爱达的错。这是一个众所周知的问题。可悲的是,这是相当unimaginatively称为“并发问题”,所以对它的引用与谷歌搜索的编程问题得到淹没。其基本要点是,你可以使对象支持传承与动态调度和所有的好东西,或者你可以让他们支持并发。以相同的语言结构做既是非常困难的。

作为实用性的问题,如果你需要一个指向自己的任务,你可以使它成为一个全球性的,或有分配它通过指针在使用某种动初始化会合的任务。我已经看到了这一点之前完成,要在职工任务的堆栈任务把自己放回“空转”堆栈当它完成。

虽然这个话题是老我碰到它跑寻找类似的自己(我的需要是允许一个任务的句柄传递给自己一个受保护的哈希表的存储区域,所有任务的访问,在影响登记)的东西

您可以在2005年的Ada做到这一点,认为它是不推荐,因为它会禁用访问检查,但它是我发现有一个任务产生的唯一方法(或发现)它自己的句柄传递到回调函数(请注意这并不排除TASK_ID传递给检查终止或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;

如果我是你,我会重新组织你的代码。所以,有一些任务与其他任务进行交互,现在2个任务。并有链表,它负责存储任务和管理任务的插入/缺失。这是应该处理同步的全局对象。

这就是为什么我建议你创建一个受保护的对象,并存储内部的任务列表。该保护通常用于被动对象,其中一些资源必须把手同步。你可以有像插入程序,删除等,这将确保只有一个创建和删除将在同一时间运行,并链表不会是不一致的。

每个任务都应该知道它的“伙伴”任务,这可能会改变时插入或取出一个任务。我建议在创建一个进入,这将更新其邻居的任务。当任务来或离开,被保护的对象将更新的邻居。

在这种情况下,无需访问“这个”指针,因为保护对象将组织一切。仅需要一个ID,该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;
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top