网络协调语言的 Ada95 实现及相关技术对比
1. 市场与店铺代理代码分析
在商业系统中,有两个关键的代码模块,分别是
MarketPlace
和
ShopAgent
。
MarketPlace
代码如下:
1. declare
2. varDist, ShopDist, Pos, PosList: int := 0;
3. varShopLoc, ShopList: loc
4. begin
5. out(1, “shop1”, d1)@self; · · ·; out(h, “shoph”, dh)@self;
6. while true do
7. in(“Shop list”, !Dist)@self;
8. newloc(ShopList);
9. while Pos ≤ h do
10. read(Pos + 1, !ShopLoc, !ShopDist)@self;
11. if ShopDist < Dist
12. then out(ShopLoc)@ShopList; PosList := PosList + 1; Pos := Pos + 1
13. else Pos := Pos + 1
14. fi
15. od;
16. out(PosList)@ShopList; out(ShopList)@self;
17. out(“List builded. . .”)@screen
18. od;
19. end
其主要功能是构建店铺列表。具体步骤如下:
1. 初始化变量,包括距离、店铺位置等。
2. 不断接收“Shop list”消息,获取距离信息。
3. 遍历所有店铺,将距离小于给定距离的店铺地址存入
ShopList
中。
4. 输出店铺列表的数量和列表本身,并在屏幕上显示列表构建完成的信息。
ShopAgent
代码如下:
1. rec ShopAgent (Cam: str; ShopList: loc; RLoc: loc; Price: int) declare
2. varNewPrice, NumShop: int;
3. varOldShop, NextShop: loc
4. begin
5. read(Cam, !NewPrice)@self;
6. if Price = 0
7. then out(Cam, self, NewPrice)@RLoc
8. else
9. if NewPrice < Price
10. then
11. in(Cam, !OldShop, !Price)@RLoc;
12. out(Cam, self, NewPrice)@RLoc;
13. Price := NewPrice
14. else nil
15. fi
16. fi;
17. in(!NumShop)@ShopList;
18. if NumShop = 1
19. then out(“go”)@RLoc
20. else
21. out(NumShop - 1)@ShopList;
22. in(!NextShop)@ShopList;
23. eval(call ShopAgent (Cam, ShopList, RLoc, Price)@NextShop
24. fi
25. end
ShopAgent
的主要功能是在各个店铺中搜索最优价格。具体步骤如下:
1. 读取相机的新价格。
2. 如果初始价格为 0,则直接输出相机信息和新价格。
3. 如果新价格小于当前价格,则更新价格信息。
4. 从店铺列表中读取店铺数量。
5. 如果只有一个店铺,则输出“go”消息。
6. 否则,更新店铺数量,获取下一个店铺地址,并在新店铺上调用
ShopAgent
继续搜索。
2. Ada95 分布模型与 Glade 工具
Ada95 分布模型将分区定义为一组可以分配到网络节点上的结构和/或算法。一个分区可以看作是两个逻辑组件的组合:
- 第一个组件实现所需应用程序的算法。
- 第二个组件定义与其他分区的通信接口。
在算法实现阶段,Ada95 程序员只需满足语言分布模型的一些约束。分区分布和通信问题与应用程序无关,可以在单独的阶段处理。在应用程序开发过程中,无需对程序将运行的架构进行假设,节点 - 分区的关联在配置阶段确定。
分区合作基于远程子程序调用机制,并通过动态调度的可能性得到增强。在运行时,根据实际参数的值可以确定要执行的程序。
Glade 工具及其配置语言专门用于指定分区定义和每个分区必须执行的机器。Glade 结合了 Ada95 的分布式和面向对象特性,它读取配置文件并为每个分区构建多个可执行文件。使用 Glade 可以创建对象物理分布在异构机器网络上的应用程序,支持不同的网络协议,并提供复制和容错功能。
3. 实现细节
3.1 编译器
为了使 Klada 程序的执行更高效,开发了一个编译器。该编译器为 Klada 程序中表达的每个节点生成一个 Ada95 分区,其中代码部分对应于分配到该节点的进程。编译器还可以进行一些静态控制,如变量声明检查、类型检查等。
每个实现节点的分区由一个本地声明的远程访问对象引用,这些对象属于
type Locality is abstract tagged limited private
类。
Locality
的方法实现了 Klaim 原语(如
in/read
、
out
、
eval
)。例如,编译器生成的将
in(t)@ℓ
翻译的代码如下:
⟨evaluate t ⟩;
⟨get s, the remote access object associated to (the name) ℓ⟩;
in(s, . . .);
其中
in
是实现
in
操作的方法。根据
s
的不同,Ada95 运行时支持将执行创建
s
的分区中的
in
过程,这就是 Ada95 的动态调度机制,它提供了在运行时确定子程序的远程子程序调用。
3.2 代码移动性
Ada95 本身不支持代码移动性,因此需要定义移动代理的编码和相应的解释器。在实现中,代理的表示如下:
type Agent Type is record
Code : Code type;
Env : Environment Type;
Mem : Memory Type;
end record
当编译器检测到代理时,会生成一个闭包,包括代理的表示(解析树)和评估逻辑位置所需的环境。编译器还会为闭包附加一个“内存”,代理可以在其中存储和检索变量的值。
代码迁移的实现是通过远程调用 Klada 解释器
kvm
并传递一个
Agent Type
对象来完成的。
kvm
通过访问对象的代码树并使用环境和内存信息来执行代理,因此
kvm
也可以被视为
Locality
类的一个方法。
3.3 动态站点创建
可以通过在操作系统 shell 中执行空站点命令向现有网络添加新的物理站点。空站点命令执行一个 Ada95 分区,该分区生成其站点地址,将其发送给名称管理器,并等待使用新站点的分区。
名称管理器处理新添加站点的列表
L
,当收到
newloc
调用时,会根据列表情况进行处理。如果列表为空,名称管理器会在调用机器上创建一个新的“虚拟”站点,这是由于
newloc
操作的非阻塞语义。
以下是动态站点创建的流程图:
graph TD;
A[执行空站点命令] --> B[生成站点地址];
B --> C[发送地址到名称管理器];
C --> D[等待使用新站点的分区];
E[收到 newloc 调用] --> F{列表 L 是否为空};
F -- 是 --> G[创建虚拟站点];
F -- 否 --> H[提供新站点地址];
4. 分布式系统编程模型对比
在开发分布式应用程序时,有两种常见的编程模型:使用操作系统网络服务和使用中间件环境。
4.1 使用操作系统网络服务
传统上,分布式应用程序使用网络编程接口(如 TCP 或 UDP 套接字)开发。程序员需要显式地调用操作系统服务,这是一项繁琐且容易出错的任务,包括初始化套接字连接、确定对等方位置、编组和解组数据结构、发送和接收消息、调试和测试多个程序以及在多个平台上移植程序等。
虽然可以将这些代码封装在包装器中以降低复杂性,但大部分代码可以自动生成。消息传递会分散开发者对应用程序领域的注意力,在分布式应用程序中使用消息传递类似于在非分布式应用程序中使用“goto”机制,这在现代编程语言中会导致显著问题。因此,更健壮的设计是使用基于过程调用的结构化方法。
4.2 使用中间件环境
中间件环境旨在提供高级抽象,以简化用户应用程序的开发。像 CORBA 或分布式计算环境(DCE)这样的环境提供了使用远程过程调用(RPC)模型开发客户端/服务器应用程序的方法。
RPC 模型受查询和回复方案的启发。与常规过程调用相比,参数与指定要使用的远程过程的数据一起被推送到流中,然后该流通过网络传输到服务器。服务器解码流,进行常规子程序调用,将输出参数和异常(如果有)放入另一个流中并发送回调用者。调用者解码流并在需要时抛出异常。
CORBA 为远程过程模型提供了与面向对象语言为经典过程语言提供的相同增强功能,包括封装、继承、类型检查和异常处理。这些功能通过接口定义语言(IDL)提供。
中间件通信框架提供了执行远程过程调用或远程对象方法调用的机制,在一定程度上是透明的。例如,每个 CORBA 接口通过对象请求代理(ORB)进行通信。用户在开发分布式应用程序时可能还需要大量复杂的服务,如位置服务和命名服务。
以下是两种编程模型的对比表格:
|编程模型|优点|缺点|
| ---- | ---- | ---- |
|使用操作系统网络服务| - 对底层网络有更细粒度的控制
- 可以根据具体需求进行定制| - 开发复杂,容易出错
- 可移植性差
- 分散开发者对应用程序逻辑的注意力|
|使用中间件环境| - 提供高级抽象,简化开发
- 支持远程过程调用,提高开发效率
- 具有封装、继承等面向对象特性| - 可能引入额外的开销
- 对底层网络的控制相对较弱|
综上所述,Ada95 在实现 Klada 语言方面有其独特的优势,但也存在一些不足,如缺乏对代码移动性的支持。而在分布式系统编程中,不同的编程模型各有优缺点,开发者需要根据具体需求选择合适的模型。未来,还可以对现有实现进行改进,如为名称管理器添加新功能,以更好地适应网络负载的变化。同时,开发更多的工具和类型,将 Klaim 原语封装成 Ada95 库,以方便编写大型分布式应用程序。
网络协调语言的 Ada95 实现及相关技术对比
5. CORBA 与 Ada 95 分布式系统附件对比
CORBA 和 Ada 95 分布式系统附件(DSA)有着不同的目标。
OMG 成立的目的是推动分布式异构应用程序开发标准的发展,CORBA 是其对象管理架构(OMA)的关键组件,是一个用于可互操作的分布式对象系统的架构。
而 Ada 95 的 DSA 则是在支持类型安全的面向对象和实时编程的语言规范语义内,为分布式系统编程提供一个模型。从实际经验来看,DSA 相较于 CORBA 有非常强大的特性,在抽象性和性能之间提供了一个有趣的平衡。CORBA 则指定了一个基于可互操作和可重用组件的灵活架构。总体目标是将 CORBA 的有趣特性提供给 DSA 用户。
6. 不同编程模型的操作步骤分析
6.1 使用操作系统网络服务的操作步骤
使用操作系统网络服务开发分布式应用程序时,具体操作步骤如下:
1.
初始化套接字连接
:
- 选择合适的网络编程接口(如 TCP 或 UDP 套接字)。
- 配置套接字的参数,如地址族、套接字类型等。
- 绑定套接字到本地地址和端口。
- 对于客户端,连接到服务器的地址和端口;对于服务器,监听客户端的连接请求。
2.
确定对等方位置
:
- 获取服务器或客户端的 IP 地址和端口号。
- 处理可能的地址转换和解析问题。
3.
编组和解组数据结构
:
- 将应用程序中的数据结构转换为适合网络传输的格式(编组)。
- 在接收端将接收到的数据转换回应用程序可识别的数据结构(解组)。
4.
发送和接收消息
:
- 使用套接字的发送和接收函数进行数据传输。
- 处理可能的网络错误和超时情况。
5.
调试和测试多个程序
:
- 使用调试工具(如调试器、日志记录)来定位和解决问题。
- 进行单元测试和集成测试,确保程序的正确性。
6.
在多个平台上移植程序
:
- 处理不同操作系统和网络接口的差异。
- 确保程序在不同平台上的兼容性。
6.2 使用中间件环境(以 CORBA 为例)的操作步骤
使用 CORBA 开发分布式应用程序的步骤如下:
1.
定义接口
:
- 使用接口定义语言(IDL)定义对象的接口。
- 包括方法的参数、返回值和异常等信息。
2.
编译 IDL 文件
:
- 使用 CORBA 提供的 IDL 编译器将 IDL 文件编译为目标语言(如 Ada、C++ 等)的代码。
3.
实现服务器端代码
:
- 实现 IDL 定义的接口的具体方法。
- 启动对象请求代理(ORB)并注册对象。
4.
实现客户端代码
:
- 获取 ORB 实例。
- 通过 ORB 查找并获取服务器对象的引用。
- 调用服务器对象的方法。
5.
配置和部署
:
- 配置 ORB 的参数,如通信协议、地址等。
- 将服务器和客户端程序部署到相应的机器上。
以下是两种编程模型操作步骤的对比列表:
|编程模型|操作步骤|
| ---- | ---- |
|使用操作系统网络服务|初始化套接字连接、确定对等方位置、编组和解组数据结构、发送和接收消息、调试和测试多个程序、在多个平台上移植程序|
|使用中间件环境(CORBA)|定义接口、编译 IDL 文件、实现服务器端代码、实现客户端代码、配置和部署|
7. 总结与展望
通过对网络协调语言的 Ada95 实现以及不同分布式系统编程模型的分析,可以看出 Ada95 在实现 Klada 语言方面有一定的优势,但代码移动性支持的缺乏是一个明显的不足。而在分布式系统编程中,使用操作系统网络服务和中间件环境各有优缺点。
未来可以进行以下改进:
-
增强名称管理器功能
:当一个站点请求新的物理站点时,如果没有可用的机器,名称管理器可以考虑在请求站点的机器上分配新站点。同时,可以改进名称管理器以考虑网络负载,选择使用较少的机器,从而更好地在整个网络上分配负载。
-
开发新工具和类型
:实现新的类型或工具,如调试器或语法驱动的编辑器,以提供更完善的编程环境。
-
创建 Ada95 库
:定义一个简单实现 Klaim 原语的 Ada95 库,这样就可以在 Ada95 程序中使用代码移动性作为编程范例,方便编写大型分布式应用程序。
以下是未来改进方向的流程图:
graph TD;
A[增强名称管理器功能] --> B[考虑网络负载分配];
C[开发新工具和类型] --> D[实现调试器和编辑器];
E[创建 Ada95 库] --> F[支持代码移动性编程];
综上所述,通过不断改进和优化,可以更好地利用 Ada95 和相关技术来开发高效、可靠的分布式应用程序。