中斷處理

中斷由沒有引數的受保護過程處理。


package Ctl_C_Handling is

   protected CTL_C_Handler is
      procedure Handle_Int with
        Interrupt_Handler,
        Attach_Handler => SIGINT;
      entry Wait_For_Int;
   private
      Pending_Int_Count : Natural := 0;
   end Ctl_C_Handler;

   task CTL_Reporter is
      entry Stop;
   end CTL_Reporter;

end Ctl_C_Handling;

包體顯示受保護過程的工作原理。在這種情況下,受保護物件中不使用布林值,因為中斷的到達速度比處理時快。任務 CTL_Reporter 處理接收的中斷。

with Ada.Text_IO; use Ada.Text_IO;
with Ctl_C_Handling; use CTL_C_Handling;
with Ada.Calendar; use Ada.Calendar;

package body Ctl_C_Handling is

   -------------------
   -- CTL_C_Handler --
   -------------------

   protected body CTL_C_Handler is

      ----------------
      -- Handle_Int --
      ----------------

      procedure Handle_Int is
      begin
         Pending_Int_Count := Pending_Int_Count + 1;
      end Handle_Int;

      ------------------
      -- Wait_For_Int --
      ------------------

      entry Wait_For_Int when Pending_Int_Count > 0 is
      begin
         Pending_Int_Count := Pending_Int_Count - 1;
      end Wait_For_Int;

   end CTL_C_Handler;

   ------------------
   -- CTL_Reporter --
   ------------------

   task body CTL_Reporter is
      type Second_Bin is mod 10;
      type History is array(Second_Bin) of Natural;

      ---------------------
      -- Display_History --
      ---------------------

      procedure Display_History(Item : History) is
         Sum : Natural := 0;
      begin
         for I in Item'Range loop
            Put_Line("Second: " & Second_Bin'Image(I) & " :" & Natural'Image(Item(I)));
            Sum := Sum + Item(I);
         end loop;
         Put_Line("Total count: " & Natural'Image(Sum));
         New_Line(2);
      end Display_History;

      One_Second_Count : Natural := 0;
      Next_Slot : Second_Bin := 0;
      Next_Second : Time := Clock + 1.0;
      Ten_Second_History : History := (Others => 0);

   begin
      loop
         Select
            Accept Stop;
            exit;
         else
            select
               CTL_C_Handler.Wait_For_Int;
               One_Second_Count := One_Second_Count + 1;
            or
               delay until Next_Second;
               Next_Second := Next_Second + 1.0;
               Ten_Second_History(Next_Slot) := One_Second_Count;
               Display_History(Ten_Second_History);
               Next_Slot := Next_Slot + 1;
               One_Second_Count := 0;
            end Select;
         end Select;
      end loop;
   end CTL_Reporter;
end Ctl_C_Handling;

執行此包的示例主程式是:

with Ctl_C_Handling; use CTL_C_Handling;

procedure Interrupt01 is
begin
   Delay 40.0;
   CTL_Reporter.Stop;
   Put_Line("Program ended.");
end Interrupt01;