Ada任务和终止

时间:2013-03-30 08:47:58

标签: multithreading task ada

我已经在http://en.wikibooks.org/wiki/Ada_Programming/Tasking阅读了一些关于ada任务的内容,并认为我会自己写一些关于任务的小事。自从我最近读了一篇关于Pintos的小课程后,我想我会实现一些读者编写算法。这是我的尝试:

procedure Test_Queue is

   type Int_Array is array(1..10) of Integer;

   task type Queue is
      entry Quit;
      entry Pop(Elem : out Integer);
      entry Push(Elem : in Integer);
   end Queue;

   task body Queue is
      Elems_In_Queue : Integer := 0;
      Q : Int_Array;
   begin
      loop
         select
            accept Push(Elem : in Integer) do
               Put_Line("Push");
               Elems_In_Queue := Elems_In_Queue + 1;
               Q(Elems_In_Queue) := Elem;
            end Push;
         or
            when Elems_In_Queue > 0 =>
               accept Pop(Elem : out Integer) do
                    Put_Line("Pop");
                Elem := Q(Elems_In_Queue);
                Elems_In_Queue := Elems_In_Queue - 1;
               end Pop;
         else
            delay 1.0;
            Put_Line("Waited");
            accept Quit;
            exit;
         end select;
      end loop;
      Put_Line("Got out of the loop");
   end Queue;

   Q : Queue;
   X : Integer;

begin
   Put_Line("Started");
   Q.Push(10);
   Put_Line("Pushed");
   Q.Push(11);
   Put_Line("Pushed");
   Q.Pop(X);
   Put_Line("Integer:" & Integer'Image(X));
   Q.Quit;
   Put_Line("Done");
end Test_Queue;

值得一提的是,我希望看到的行为是,当没有对队列/堆栈进行操作(推/弹)1秒钟时,我希望任务终止/退出无限循环。 / p>

但这只是输出“已启动”然后转到我的延迟1.0并输出“等待”。这不完全是我的预期,因为我至少接受了推,这是我打电话的第一件事。我在哪里想错了,为什么这不起作用?另外,还有更多的资料来源,如何在Ada中进行任务分配?我设法通过在2个不同的任务中创建一个Semaphore和Lock来实现这一点,但这似乎是一个糟糕的解决方案而不是非常adaesque。

1 个答案:

答案 0 :(得分:4)

改进了诊断后,很明显在启动时,Select替代方案都没有立即可用,因此队列任务直接进入Else部分,延迟1秒后等待接受Quit

与此同时,主要任务是阻止其第一次(无条件,不定时!)Push条目调用,以便它永远不会发出Quit条目调用。结果:死锁。

解决方案(第08页Burns & Welling中所述)只是将ELSE更改为OR,以便第三个(延迟)选项仍然是Select替代选项。然后在每次迭代中,最早的(推,弹或延迟)将被接受。