Concurrency 中止Ada中使用重新请求的受保护对象的进程

Concurrency 中止Ada中使用重新请求的受保护对象的进程,concurrency,task,ada,protected-resource,Concurrency,Task,Ada,Protected Resource,我的程序遇到了一些问题 我有一个调用函数(Take_Job)的进程,该函数在一段时间(最小等待时间)过去之前应该保持阻塞状态。如果不是这样,将出现一条消息,通知这种情况 for Printer_Id in Type_Printer_Id loop select delay MINIMUM_WAIT Pragma_Assert (True, ""); then abort Take_Job (Controller,

我的程序遇到了一些问题

我有一个调用函数(Take_Job)的进程,该函数在一段时间(最小等待时间)过去之前应该保持阻塞状态。如果不是这样,将出现一条消息,通知这种情况

for Printer_Id in Type_Printer_Id loop
   select
      delay MINIMUM_WAIT
      Pragma_Assert (True, "");
   then abort
      Take_Job (Controller,
                     Printer_Id,
                     Max_Tonner,
                     Job,
                     Change_Tonner);
      Pragma_Assert
        (False,
           "Testing of Take_Job hasn't been successful. It should have remained blocked.");
   end select;
end loop;
函数Take_Job调用受保护对象中的条目:

procedure Take_Job (R                 : in out Controller_Type;
                         Printer      : in     Type_Printer_Id;
                         Siz          : in     Typo_Volume;
                         Job          :    out Typo_Job;
                         Excep_Tonner :    out Boolean) is
begin
   R.Take_Job(Printer, Siz, Job, Excep_Tonner);
end Take_Job;
其中“R”是受保护对象

以下代码是受保护对象的条目。实际上,“when”条件是真的,因为我需要用条目的参数检查一些内容。由于Ada不允许我这样做,我复制受保护对象内的参数并调用“延迟条目”,然后在“延迟条目”中,我将确保在继续之前满足条件

entry Take_Job(Printer_Id: in Type_Printer_Id; Remaining: in Type_Volume; Job: out Type_Job; exceptionTonner: out Boolean)
when True is
begin
   Copy_Remaining(Printer_Id) := Remaining;
   requeue Take_Job_Delayed(Printer_Id);
end Take_Job;
让我们看看“延迟进入”代码:

假设我的目标是通过最小的等待并运行“Pragma_断言(True)”)。如果我将Take_Job的“when”条件设置为“False”,则一切正常。Take_作业永远不会被接受,将执行Pragma_断言。如果我将其设置为“True”,将Take_Job_的“when”条件延迟为“False”,则不会得到相同的效果,进程将被阻止,并且不会执行任何Pragma_断言


为什么??问题似乎出现在“重新查询”中或附近,但为什么会发生这种情况?

您需要使用abort执行重新查询

entry Take_Job(Printer_Id: in Type_Printer_Id;
               Remaining: in Type_Volume;
               Job: out Type_Job;
               exceptionTonner: out Boolean)
when True is
begin
   Copy_Remaining(Printer_Id) := Remaining;
   requeue Take_Job_Delayed(Printer_Id) with abort;
end Take_Job;
否则,将失去中止入口调用的机会。在Burns&Wellings中有详细说明,并有更易于理解的解释

entry Take_Job(Printer_Id: in Type_Printer_Id;
               Remaining: in Type_Volume;
               Job: out Type_Job;
               exceptionTonner: out Boolean)
when True is
begin
   Copy_Remaining(Printer_Id) := Remaining;
   requeue Take_Job_Delayed(Printer_Id) with abort;
end Take_Job;