我的代码引发了TASKING_ERROR?

pra*_* pp 5 concurrency ada task

假定以下情况:有一个用于存放硬币的盒子人们从盒子里拿钱人们在盒子里放钱我已经将任务输入为Add,Subtract,Read和Write。下面是我的代码。现在我很困惑如何调用条目加,减和阅读以达到上述要求,请帮助

   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;
Run Code Online (Sandbox Code Playgroud)

Sim*_*ght 2

在这里,您的程序产生输出

\n\n
$ ./protected_imp \ncoins 6\nno request received for 5 secondsno request received for 5 secondsno request received for 5 seconds^C\n
Run Code Online (Sandbox Code Playgroud)\n\n

(我当时就停止了)。

\n\n

\xe2\x80\x9ccoins 6\xe2\x80\x9d 正是它应该给出的输出;您\xe2\x80\x99 已将 1 添加到起始值 (1) 5 次。

\n\n

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

\n\n

事件的顺序是

\n\n
task arrives at select; all the alternatives are closed\nmain calls go.add (1)'\ntask accepts the entry, increments x, exits the select, and goes round the loop again to wait at the select\nmain calls go.add (1)\ntask accepts the entry, increments x, exits the select, and goes round the loop again to wait at the select\nmain calls go.add (1)\ntask accepts the entry, increments x, exits the select, and goes round the loop again to wait at the select\nmain calls go.add (1)\ntask accepts the entry, increments x, exits the select, and goes round the loop again to wait at the select\nmain calls go.add (1)\ntask accepts the entry, increments x, exits the select, and goes round the loop again to wait at the select\nmain calls go.read\ntask accepts the entry, prints out \xe2\x80\x9ccoins 6\xe2\x80\x9d, and goes round the loop again to wait at the select\nmain finishes and waits until the task terminates, which it doesn\xe2\x80\x99t, because\nafter 5 seconds, the select\xe2\x80\x99s 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\nafter 5 seconds, the select\xe2\x80\x99s delay alternative opens, so the task takes it, prints the message and goes round the loop again to wait at the select\n...\n
Run Code Online (Sandbox Code Playgroud)\n