具体而言,是有任务的方式来获得对自身的引用?
例如:
task type someTask;
type someTaskAccessor is access someTask;
task body someTask is
pointerToTask : someTaskAccessor;
begin
pointerToTask = this;
end someTask;
具体而言,是有任务的方式来获得对自身的引用?
例如:
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;