我最近开始编程Ada,现在我被困了。我创建了一个包含多个任务的程序。主要任务是管理传入通信,因此启动工作任务或将数据传输到工作任务。工作任务都是相同类型但具有不同的标识符。他们做他们的工作,并应该在那之后完成。例如:
task body Access_Protected is
begin
accept Start(foo: in Integer; foo2: out Integer)
do something
end Start;
while Go_loop loop
select
accept Quit do
Go_loop := false;
end Quit;
or
accept Insert(foo3: in Integer)
do something
if something = 0 then
Go_loop := false;
end if;
end Insert;
or delay 2.0;
end select;
end loop;
end Access_Protected;
我知道当Go_loop完成时应该终止工作任务。我对吗?它可以启动任务一次,但是当主任务尝试通过调用Start过程重新启动工作任务时,没有任何反应。有人可以告诉我,我错过了哪一点。
task
和子程序有些相关,因为当身体完成时,构造结束,也就是说构造以其适当的end
结束;在procedure
控制的情况下,返回到调用者,在function
的情况下,引发异常PROGRAM_ERROR
,并且在task
的情况下,控制“线程”终止。
在您的特定问题中发生的事情似乎归结为以下几点:
Package Example is
Task Type Message_Task is
Entry Execute;
End Message_Task;
End Example;
Package Body Example is
Task Body Message_Task is
Use Ada.Text_IO;
Begin
accept Execute do
Put_Line( "Rendezvous!" );
end Execute;
delay 0.2; -- Stub delay.
Put_Line( "Finishing Task." );
-- Task Ends Here.
End Message_Task;
End Example;
--...
Test : Example.Message_Task;
--...
Test.Execute;
-- Test.Execute can't be accepted here because it can only accept "Execute"
-- the one time, as per the body's definition.
这真的像你的问题是因为,同样一旦你说“X.Start(1,2)
”另一个调用Start
没有重置任务执行的位置回到接受。
如果您希望任务“保持活力”以进行进一步处理,您可以执行以下两个选项之一。
选项1 - 设置'协议':
Package Example is
Task Type Message_Task is
Entry Initialization;
Entry Execute;
Entry Quit;
End Message_Task;
End Example;
Package Body Example is
Task Body Message_Task is
Use Ada.Text_IO;
Has_quit : Boolean := False;
Begin
Main:
loop
select
accept Initialization do
null;
end Initialization;
accept Execute do
null;
end Execute;
or
accept Quit do
Has_Quit := True;
end Quit;
end select;
Exit Main when Has_Quit;
end loop Main;
End Message_Task;
End Example;
选项2 - 允许终止。
Package Example is
Task Type Message_Task is
Entry Initialization;
Entry Execute;
End Message_Task;
End Example;
Package Body Example is
Task Body Message_Task is
Use Ada.Text_IO;
Has_quit : Boolean := False;
Begin
accept Initialization do
null;
end Initialization;
Main:
loop
select
accept Execute do
null;
end Execute;
or
terminate;
end select;
end loop Main;
End Message_Task;
End Example;
微妙的差异是选项2摆脱了Quit
条目,允许任务'休息'在terminate
替代,而选项1更明确的控制(并在某些情况下需要),但要求成对调用Initialization
和Execute
。
任务只会运行到其主要语句序列的末尾(忽略各种技术细节)。
如果您希望任务执行某些操作,然后暂停直到收到外部触发器,则应该围绕任务主体中的语句循环。