如何在Ada包中实现单例日志任务?隐藏任务并保持全程活跃
实现隐藏在Ada日志包内的单例Logger任务
没问题,要把Logger任务藏在Log包内部且作为单例全程活跃,其实很简单——我们只需要把任务定义放在包体内部(这样客户端完全看不到它),利用Ada包的初始化机制让任务自动启动,同时调整原有的log过程,让它把消息转发给内部任务的entry即可。
修改后的完整代码
log.ads(包规范保持不变,对客户端完全兼容)
package Log is procedure log (text: String); end Log;
log.adb(包体中嵌入隐藏的Logger任务)
with Ada.Text_IO; package body Log is -- 把Logger任务定义在包体内部,客户端无法访问 task Logger_Task is entry log (text : String); end Logger_Task; task body Logger_Task is begin loop accept log (text: String) do Ada.Text_IO.Put (text); end log; end loop; end Logger_Task; -- 原有的log过程现在只负责向任务发送消息 procedure log (text: String) is begin Logger_Task.log (text); end log; end Log;
test.adb(调用代码完全不需要修改)
with Log; procedure Test is begin Log.log ("bla bla"); end Test;
关键细节说明
- 任务的隐藏性:因为
Logger_Task是定义在Log包体内部的,包规范里完全没有提及它,所以客户端(比如Test程序)根本不知道这个任务的存在,完美实现封装。 - 单例与自动激活:Ada的包体在程序启动时只会被初始化一次,而包体内部的任务会在包体初始化时自动激活运行。这意味着
Logger_Task从程序启动到结束都会保持活跃,而且全程只有这一个实例,天然就是单例。 - 无限循环的作用:任务里的
loop会让它一直等待logentry的调用,只要程序在运行,它就会持续处理所有来自客户端的日志请求。
这样修改后,既保留了原有的API兼容性,又实现了用后台任务异步处理日志的需求,同时完全隐藏了任务的实现细节~
内容的提问来源于stack exchange,提问作者ols
相关产品推荐
相关产品推荐

