【问题标题】:Access two entries of one task at the same time by different tasks不同任务同时访问一个任务的两个条目
【发布时间】:2015-05-13 13:07:17
【问题描述】:

我需要通过两个不同的任务访问一个任务的两个不同条目。看起来我对 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 正在访问第一个条目并进入无限循环,第二个无法访问第二个条目。我明白它为什么会发生,但我想不出可能有用的东西。 也许有类似接受第一(..)和接受第二(..)的东西。 提前谢谢!

【问题讨论】:

  • 我认为您需要从外部告诉我们您想要发生的事情(不能涉及counter,因为它是main_task 本地的)。
  • 从字面上看,我需要对一台机器(任务)进行编程,该机器(任务)需要两个工人(工人是一组任务)同时按下两个不同的按钮,以便机器能够做某事。

标签: multithreading task ada


【解决方案1】:

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

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;

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

【讨论】:

  • 我知道我错过了一些东西——accept 里面的accept 是诀窍,非常感谢
【解决方案2】:

您需要有一个 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;

应该是这样的结构。

【讨论】:

  • 为什么i := i + 1 在accept increment 后面,而i := i - 1 在accept decrement 里面? (只是好奇)
  • 我最初有这个用于一些教学材料,我会用它来演示集合模型的不同方面。
猜你喜欢
  • 2019-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-01
  • 2014-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多