再次启动任务

时间:2017-07-12 15:00:29

标签: ada multitasking

我最近开始使用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过程重新启动工作任务时,没有任何反应。 有人可以告诉我我错过了哪一点。

2 个答案:

答案 0 :(得分:3)

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成对调用。

答案 1 :(得分:2)

任务只有在到达主要语句序列的末尾才会运行(忽略各种技术细节)。

如果你想要一个任务做某事,然后暂停直到它收到一个外部触发器,你应该围绕你在任务体中的语句循环。