再次启动任务

问题描述 投票:0回答:2

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

ada multitasking
2个回答
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更明确的控制(并在某些情况下需要),但要求成对调用InitializationExecute


2
投票

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

如果您希望任务执行某些操作,然后暂停直到收到外部触发器,则应该围绕任务主体中的语句循环。

© www.soinside.com 2019 - 2024. All rights reserved.