首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Ada关闭挂钩

Ada关闭挂钩
EN

Stack Overflow用户
提问于 2011-05-19 08:11:19
回答 6查看 1.2K关注 0票数 12

在关闭/终止Ada应用程序时,我希望调用一些“cleanup”调用。

例如,如果我在java中,我会这样做,以达到在关机时获得某种调用的效果:

代码语言:javascript
复制
Runtime.getRuntime().addShutdownHook(new Thread(){
       public void run(){
            method();
       }
});

在Ada中有没有类似的东西,或者其他实现这一点的方法?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-05-19 14:53:13

您可以为main过程创建一个受控(或Limited_Controlled)对象,该对象在其Finalization方法中调用必要的内容。

请注意,您不能访问main过程的任何局部变量,因此请将任何必要的内容放入受控对象中。

示例:

代码语言:javascript
复制
with Ada.Text_IO;
with Ada.Finalization;
procedure Main is
   type Cleaner is new Ada.Finalization.Limited_Controlled with record
      Some_Interesting_Data : Integer;
   end record;
   overriding procedure Finalize (X : in out Cleaner) is
   begin
      Ada.Text_IO.Put_Line ("Cleaning..." & Integer'Image (X.Some_Interesting_Data));
   end Finalize;
   The_Cleaner : Cleaner;
begin
   Ada.Text_IO.Put_Line ("Main Procedure.");
   The_Cleaner.Some_Interesting_Data := 42;
   Ada.Text_IO.Put_Line ("Finished.");
end Main;
票数 8
EN

Stack Overflow用户

发布于 2011-05-19 21:21:51

由于Ada主程序被视为一项任务,因此您可以使用Ada.Task_Termination包来管理执行后的清理。在Ada 2005 Rationale中有一篇关于这方面的文章,下面是我在这个示例的基础上放在一起的一个快速演示。

你必须提供一个库级别的受保护的终止过程,所以这里有一个包:

代码语言:javascript
复制
with Ada.Task_Termination;
with Ada.Task_Identification;
with Ada.Exceptions;

package Main_Program_Finalization is

   protected Shutdown_Handler is

      procedure Termination_Finalizer 
        (Cause : in Ada.Task_Termination.Cause_Of_Termination;
         T     : in Ada.Task_Identification.Task_Id;
         X     : in Ada.Exceptions.Exception_Occurrence);
   end Shutdown_Handler;

end Main_Program_Finalization;

正文:

代码语言:javascript
复制
with Text_IO; use Text_IO;

package body Main_Program_Finalization is

   protected body Shutdown_Handler is

      procedure Termination_Finalizer
        (Cause : in Ada.Task_Termination.Cause_Of_Termination;
         T     : in Ada.Task_Identification.Task_Id;
         X     : in Ada.Exceptions.Exception_Occurrence)
      is
         use Ada.Task_Termination;
         use Ada.Task_Identification;
         use Ada.Exceptions;
      begin
         New_Line;
         Put_Line("Shutdown information:");
         New_Line;
         case Cause is
         when Normal =>
            Put_Line("Normal, boring termination");
         when Abnormal =>
            Put_Line("Something nasty happened to task ");
            Put_Line(Image(T));
         when Unhandled_Exception =>
            Put_Line("Unhandled exception occurred in task ");
            Put_Line(Image(T));
            Put_Line(Exception_Information(X));
         end case;
      end Termination_Finalizer;

   end Shutdown_Handler;

end Main_Program_Finalization;

主程序(它是为posted时的正常终止设置的,取消最后两行的注释并运行它,以查看未处理的异常触发终止的效果):

代码语言:javascript
复制
with Main_Program_Finalization;
with Ada.Task_Identification;
with Ada.Task_Termination;
with Text_IO; use Text_IO;

procedure task_term is

   use Ada;

   Task_ID : Task_Identification.Task_Id
     := Task_Identification.Current_Task;

begin
   Put_Line("Main Task ID: " & Task_Identification.Image(Task_ID));

   Put_Line("Setting termination finalizer");
   Task_Termination.Set_Specific_Handler
     (Task_ID, 
      Main_Program_Finalization.Shutdown_Handler.Termination_Finalizer'Access);
   Put_Line("Go off and do things now...");
   delay 1.0;
   Put_Line("Done with mainline processing, the shutdown handler should now execute");

--     Put_Line("Raise an unhandled exception and see what the shutdown handler does");
--     raise Constraint_Error;
end Task_Term;
票数 11
EN

Stack Overflow用户

发布于 2011-05-19 14:00:34

如果它是由用户发起的受控关闭,或者因为程序只是完成了它所做的事情,那么您可以简单地添加一个对清理过程的最终调用。

如果程序由于中断信号而终止,例如用户发送SIGINT信号或系统关闭,则可以捕获这些信号并将清理过程放入已注册的回调中。

我写了一个关于如何使用Ada捕获中断的简短示例。它可以在github上获得,也可以作为wiki article使用。

另一种选择是使用libre.adacore.com提供的Florist POSIX包。也许在posix-signals包中有一些用处。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6052450

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档