我的代码提出了TASKING_ERROR?

时间:2015-01-25 15:50:06

标签: concurrency task ada

假设以下情况: 有一个盒子,用来存放硬币 人们从盒子里拿钱 人们把钱放进盒子里 我已将任务输入作为添加,减去,读取和写入。下面是我的代码。现在我很困惑如何调用条目添加,减去和读取以达到上述要求请帮助

   with Ada.Text_IO,ada.integer_text_io;
   use ada.text_io,ada.integer_text_io;
     procedure protected_imp is
     task type box(initial_value:integer;min_value:integer;max_value:integer) is
     entry add(number:integer); 
     entry subtract(number:integer);
     entry read;
      end box;
  task body box is 
  x:integer:=initial_value; --shared variable
   begin
   loop                  --why raised TASKING_ERROR when loop is removed?
select
   when x<max_value=>
   accept add(number:integer)do
   x:=x+number;
   end add;
or  
    when x>min_value=>
    accept subtract(number:integer) do
    x:=x-number;
    end subtract;
or
    accept read do
    put("coins");
    put_line(integer'image(x));
    end read;
or
   delay(5.0);
  put("no request received for 5 seconds");
  end select;
 end loop;
 end box;
  go:box(1,0,10);
  begin ----- how to call? and why  i am getting "no request received for 5 seconds " even i have activate go .add(1) ?
  for i in 1..5 loop
   go.add(1);
   end loop;
    go.read;
  end protected_imp;

1 个答案:

答案 0 :(得分:2)

这里,你的程序产生输出

$ ./protected_imp 
coins 6
no request received for 5 secondsno request received for 5 secondsno request received for 5 seconds^C

(我在那时停了下来。)

“硬币6”正是它应该给出的输出;你已经将1加到起始值(1)5次。

如果删除循环,则获得Tasking_Error的原因是该任务执行select语句一次;在接受go.add调用后,它会退出select并退出任务的底部,以便下一个go.add调用无处可去,因为不再有任务。

事件顺序是

task arrives at select; all the alternatives are closed
main calls go.add (1)'
task accepts the entry, increments x, exits the select, and goes round the loop again to wait at the select
main calls go.add (1)
task accepts the entry, increments x, exits the select, and goes round the loop again to wait at the select
main calls go.add (1)
task accepts the entry, increments x, exits the select, and goes round the loop again to wait at the select
main calls go.add (1)
task accepts the entry, increments x, exits the select, and goes round the loop again to wait at the select
main calls go.add (1)
task accepts the entry, increments x, exits the select, and goes round the loop again to wait at the select
main calls go.read
task accepts the entry, prints out “coins 6”, and goes round the loop again to wait at the select
main finishes and waits until the task terminates, which it doesn’t, because
after 5 seconds, the select’s delay alternative opens, so the task takes it, prints the message (it should really use Put_Line) and goes round the loop again to wait at the select
after 5 seconds, the select’s delay alternative opens, so the task takes it, prints the message and goes round the loop again to wait at the select
...