有一些’清理’调用,我希望在调用时调用 阿达 </跨度> 应用程序被关闭/杀死。
例如,如果我在java中,我会做这样的事情来实现有一些东西的效果……在关机时调用:
Runtime.getRuntime()。addShutdownHook(new Thread(){ public void run(){ 方法(); }});
是否有类似的东西 阿达 </跨度> 或另一种方法来实现这一目标? …
如果它是由用户启动的受控关闭,或者因为程序只是完成它所做的事情,那么你可以简单地添加一个最终调用清理程序。
如果由于中断信号(例如用户发送SIGINT信号)或系统关闭而终止程序,则可以捕获这些信号并将清理过程放入已注册的回调中。
我写了一个关于如何使用Ada捕获中断的简短示例。它可以在 github上 并作为一个 维基文章 。
另一个选择是使用Florist POSIX包 libre.adacore.com 。也许在posix-signals包中有一些用处。
您可以为主过程创建一个受控(或Limited_Controlled)对象,该过程在其Finalization方法中调用必要的东西。
请注意,您无法访问主过程的任何局部变量,因此请将任何必要的内容放入受控对象中。
例:
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;
如果允许程序很好地关闭,那么您可以使用受控类型等标准语言工具来提供“关闭时”行为。
如果操作系统不允许程序很好地关闭,那么 的 在任何语言中都没有语言定义的方法 强> 。您将不得不使用某种OS调用来执行此操作。
注意 的 您展示的示例不是Java调用,而是JVM调用 强> 。 JVM = Java虚拟机......本质上是Java OS。假设您的Ada代码在JVM上运行,您可以从Ada进行完全相同的调用。如果您在Windows下运行,则必须使用Win32系统调用。你可以从Ada制作那些,但很明显,确切的调用在语言中没有可移植的定义。
由于Ada主程序被视为任务,您可以使用 Ada.Task_Termination 用于管理执行后清理的包。在这里有一篇关于此的文章 Ada 2005理由 以下是我在一个示例的基础上编写的快速演示。
您必须提供库级保护终止过程,因此这是一个包:
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;
身体:
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;
主程序(设置为已发布的正常终止,取消注释最后两行并运行它以查看未处理的异常触发终止的影响):
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;
似乎应该有一种方法在纯Ada中做到这一点,但我找不到一个。
一个想法是使用Interfaces.C并调用 atexit对() 使用回调函数进行清理。我没有尝试过,但我想不出有什么理由不行。
关于来自C的Ada回调的更多信息