2014-02-20 33 views
4

我的程序遇到了一些麻煩。在Ada中取消使用受保護對象的流程

我有一個進程調用一個函數(Take_Job),該函數在時間(MINIMUM_WAIT)通過之前應該保持阻塞狀態。如果沒有發生這種情況,將會出現一條通知這種情況的消息。

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; 

讓我們來看看「延遲進入」代碼:

entry Take_Job_Delayed(for J in Type_Printer_Id)(Printer_Id: in Type_Printer_Id; Remaining: in Type_Volume; Job: out Type_Job; exceptionTonner: out Boolean) 
when False is -- I've done this on purpose 
begin 
    null; -- Actually, there would be a lot of code here 
end Take_Job_Delayed; 

比方說,我的目標是要通過MINIMUM_WAIT並運行「Pragma_Assert(沒錯,‘’)」。如果我把Take_Job的「when」條件設置爲「False」,那麼一切正常。 Take_Job永遠不會被接受,並且Pragma_Assert將被執行。如果我將它設置爲「True」,並且Take_Job_Delayed的「when」條件爲「False」,我不會得到相同的效果,並且進程被阻止,Pragma_Asserts也不會執行。

爲什麼?看起來問題出現在「要求」或其附近,但爲什麼會發生這種情況?

回答

5

您需要執行請求with 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; 

因爲否則機會中止輸入呼叫已丟失。在ARM 9.5.4有詳細資料,並且在Burns & Wellings,「Concurrency in Ada」中有一個更加可以理解的解釋。

+0

你是對的。 – ArthurTheLearner