不同任务同时访问一个任务的两个条目

Access two entries of one task at the same time by different tasks

我需要通过两个不同的任务访问一个任务的两个不同条目。看起来我对 Ada 的了解不足以执行此操作,我也花了很多时间寻找解决方案但没有效果。我尝试使用受保护类型作为管理器,但没有用。我希望我的访问任务在每个条目中将计数器递增 1,然后在计数器达到 2 后在第一个条目中执行更多工作。我的方法是这样的

  task mainTask is
      entry first(n : in Integer);
      entry second(n : in Integer);
  end mainTask;
  task body mainTask is
      counter : Integer := 0;
  begin
  loop
     accept first(n : in Integer) do
        loop
           counter := counter + 1;
           Put_Line("First one working");
           --loop and wait until counter is 2
           --perform rest of the code
           delay 1.0;
        end loop;
     end first;
     accept second(n : in Integer) do
        loop
           counter := counter + 1;
           Put_Line("Second one working");
           delay 1.0;
        end loop;
     end second;
  end loop;
end mainTask;

task firstTask;
task body firstTask is
begin
   mainTask.first(0);
end firstTask;

task secondTask;
task body secondTask is
begin
   mainTask.second(0);
end secondTask;

在运行之后,firstTask正在访问第一个条目并进入无限循环,第二个无法访问第二个条目。我明白为什么会这样,但我想不出可能有用的东西。 也许有类似 accept first(..) 和 accept second(..) 的东西。 提前致谢!

您需要有一个 select 语句 - 这将允许调用任务选择任何可能打开的选项(第一、第二)。 目前你有两个无限循环,所以如果第二次接受发生,我会感到惊讶。

所以...

task multiple_entry is
    entry increment;
    entry decrement;
end multiple_entry;

task body multiple_entry is
    i : integer;
begin
    select
        accept increment;
        i := i + 1;
    or
        accept decrement do
            i := i - 1;
        end decrement
    or
        terminate;
    end select;
end;

它应该如何构建。

如果你真的想要“一台机器(任务)需要两个工人(工人是一组任务)同时按下两个不同的按钮,这样机器就能做某事”,就像你的回复我的评论,你可以考虑在你的代码中明确说明这一点;比如

task body Main is
begin
   loop
      select
         accept First_Button_Pressed;
         select
            accept Second_Button_Pressed;
            Put_Line ("second pressed while first pressed");
         or
            accept First_Button_Released;
            Put_Line ("first released");
         or
            terminate;
         end select;
      or
         accept Second_Button_Pressed;
         select
            accept First_Button_Pressed;
            Put_Line ("first pressed while second pressed");
         or
            accept Second_Button_Released;
            Put_Line ("second released");
         or
            terminate;
         end select;
      or
         accept First_Button_Released;
         Put_Line ("first released");
      or
         accept Second_Button_Released;
         Put_Line ("second released");
      or
         terminate;
      end select;
   end loop;
end Main;

但显然,如果您必须扩展代码以处理更多按钮,这将不容易维护!