中斷處理
中斷由沒有引數的受保護過程處理。
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;